86266


python で temp directory を作ってその中にいろいろ中間結果を出力してるんですが  
これをマルチプロセス化したところ子プロセスで temp directory が見つからない謎な現象に遭遇しました  
毎回ではなく時々 False になります

原因わかる方いらっしゃいますでしょうか

再現する最小単位まで削ったコード

[code]

    import tempfile
    import os
    import sys
    import time
    
    def main():
      global tmp_dir
    
      # tmpdir 作成
      tmp_dir_obj = tempfile.TemporaryDirectory()
      tmp_dir = tmp_dir_obj.name
      print(tmp_dir)
      print(os.path.exists(tmp_dir))
    
      n_process = 4
    
      # プロセスを４つ作る
      pids = list(range(n_process))
      for i in range(n_process):
        pid = os.fork()
        if pid:  # 親プロセスは子プロセスIDを記憶して続行
          pids[i] = pid
    
        else:  # 子プロセスは start をよんで終了
          start()
          sys.exit()
    
      # ここからは親のみ
    
      # 子プロセスを全部まつ
      print('#wait pid')
      print(pids)
      for pid in pids:
        os.waitpid(pid, 0)
        print(f'join {pid}')
    
      # メッセージ表示して temp 削除
      print('#tmp clean')
      tmp_dir_obj.cleanup()
    
    
    def start():
      time.sleep(1)
      # tmp_dir があるか確認
      print(tmp_dir)
      print(os.path.exists(tmp_dir))
    
    
    if __name__ == '__main__':
      main()
    
[/code]

実行結果

[code]

    # python tmp_dir_test.py
    /var/folders/4t/ktwsj9q134l5dry9p2xpwfnh0000gq/T/tmpi1xjdjac
    True
    #wait pid
    [28132, 28133, 28134, 28135]
    /var/folders/4t/ktwsj9q134l5dry9p2xpwfnh0000gq/T/tmpi1xjdjac
    True
    /var/folders/4t/ktwsj9q134l5dry9p2xpwfnh0000gq/T/tmpi1xjdjac
    False
    /var/folders/4t/ktwsj9q134l5dry9p2xpwfnh0000gq/T/tmpi1xjdjac
    False
    /var/folders/4t/ktwsj9q134l5dry9p2xpwfnh0000gq/T/tmpi1xjdjac
    False
    join 28132
    join 28133
    join 28134
    join 28135
    #tmp clean
    
[/code]

* * *

OS は Mac  
Python 3.9.0 です


CC BY-SA 4.0
2022-02-09T10:54:23.897
86231
2022-02-11T09:54:58.770
2022-02-09T11:02:49.723
question
python
python マルチプロセスで temporary directory が時々みえなくなる謎


> python で temp directory を作ってその中にいろいろ中間結果を出力してるんですが  
>  これをマルチプロセス化したところ子プロセスで temp directory が見つからない謎な現象に遭遇しました 毎回ではなく時々  
>  False になります

生成するプロセス数を増やすと現象の再現性が高くなります。  
こちらの環境(※)で実行したところ、`n_process =
8`の場合、5プロセス目以降でほぼ確実に`os.path.exists(tmp_dir)`がFalseになります。

※ 確認した環境は以下です。

  * Ubuntu 20.04.3 LTS
  * Python 3.9.5

> 原因わかる方いらっしゃいますでしょうか

straceで確認したところ、最初に子プロセスが終了した時点でディレクトリが削除されていました。  
生成したプロセスの終了を待ち合わせている処理である

[code]

    os.waitpid(pid, 0)
    
[/code]

の直後にディレクトリは存在していませんでした。  
`tmp_dir_obj.cleanup()`が実行される前にディレクトリは削除されています。

* * *

<https://docs.python.org/ja/3/library/tempfile.html>  
によると、  
「コンテキストの完了または一時ディレクトリオブジェクトの破棄により、新しく作成された一時ディレクトリとそのすべてのコンテンツがファイルシステムから削除される。」とあります。

最初にプロセスが終了した時点で「一時ディレクトリオブジェクトの破棄」が行われ、ディレクトリが削除されたのだと思います。


CC BY-SA 4.0
2022-02-11T07:40:19.170
86266
2022-02-11T09:54:58.770
2022-02-11T09:54:58.770
35558
35558
86231
answer