我在集群系统上有几个并行运行的线程。每个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
我怀疑这可能是由于竞争条件导致一个作业在另一个作业之前创建了 dir 。这可能吗?如果是这样,如何避免这种错误?
我不确定这是一个竞争条件,所以想知道Python中的其他问题是否会导致这个奇怪的错误。
答案 0 :(得分:44)
任何时候代码都可以在您检查某些内容和执行操作之间执行,您将遇到竞争条件。避免这种情况的一种方法(以及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 :(得分:37)
从Python >=3.2
开始,os.makedirs()
可以采用第三个可选参数exist_ok
:
os.makedirs(mydir, exist_ok=True)
答案 2 :(得分:15)
捕获异常,如果errno为17,则忽略它。如果isdir
和makedirs
来电之间存在竞争条件,那么这是唯一可以做的事情。
但是,也可能存在具有相同名称的文件 - 在这种情况下os.path.exists
将返回True
但os.path.isdir
返回false。
答案 3 :(得分:1)
我有类似的问题,这就是我做的事情
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()检查路径来完成,并在那里我们传递了相应的目录名。
答案 4 :(得分:0)
要忽略目录或文件存在错误,可以尝试以下操作:
except OSError, e:
if e.errno != 17:
print("Error:", e)