クラスターシステムでPython=から複数のスレッドが並列に実行されています。各pythonスレッドはディレクトリmydir
に出力します。各スクリプトは、前にmydirが存在するかどうかをチェックし、存在しない場合は作成します。
if not os.path.isdir(mydir):
os.makedirs(mydir)
しかし、これはエラーをもたらします:
os.makedirs(self.log_dir)
File "/usr/lib/python2.6/os.py", line 157, in makedirs
mkdir(name,mode)
OSError: [Errno 17] File exists
1つのジョブがdirを作成してから、他のジョブがそれに到達するという競合状態が原因である可能性があります。これは可能ですか?もしそうなら、このエラーをどのように回避できますか?
私はそれが競合状態であるかどうかわからないので、Pythonの他の問題がこの奇妙なエラーを引き起こす可能性があるかどうか疑問に思っていました。
何かをチェックしてからアクションを実行するまでの間にコードが実行できるときはいつでも、競合状態になります。これを回避する1つの方法(およびPythonでの通常の方法)は、例外を試してから処理することです
while True:
mydir = next_dir_name()
try:
os.makedirs(mydir)
break
except OSError, e:
if e.errno != os.errno.EEXIST:
raise
# time.sleep might help here
pass
予測可能な一連のディレクトリを作成しようとするスレッドが多数ある場合でも、これは多くの例外を発生させますが、最終的にはそこに到達します。その場合、dirsを作成するスレッドを1つだけ持つ方が良い
Python _>=3.2
_以降、os.makedirs()
は3番目のオプションの引数_exist_ok
_を取ることができます:
_os.makedirs(mydir, exist_ok=True)
_
例外をキャッチし、errnoが17の場合は無視してください。 isdir
とmakedirs
の呼び出しの間に競合状態がある場合に実行できるのは、これだけです。
ただし、同じ名前のfileが存在する可能性もあります。その場合、os.path.exists
はTrue
を返しますが、os.path.isdir
はfalseを返します。
私は同様の問題があり、ここに私がやったことがあります
try:
if not os.path.exists(os.path.dirname(mydir)):
os.makedirs(os.path.dirname(mydir))
except OSError as err:
print(err)
説明:ディレクトリがすでに存在するかどうかを確認するだけでこのエラーメッセージがスローされます[Errno 17]ファイルが存在するディレクトリ名存在するかどうかmydir値のディレクトリ名を返しますが、すでに存在するかどうかはわかりません。見逃されているのは、そのディレクトリがすでに存在するかどうかのチェックではありません。パスをos.path.exists()でチェックすることで確認でき、そこにそれぞれのディレクトリ名を渡しました。
Dirまたはfile existエラーを無視するには、次のことを試してください。
except OSError, e:
if e.errno != 17:
print("Error:", e)