【发布时间】:2015-08-05 02:31:43
【问题描述】:
我有以下代码(为清楚起见进行了简化):
import os
import errno
import imp
lib_dir = os.path.expanduser('~/.brian/cython_extensions')
module_name = '_cython_magic_5'
module_path = os.path.join(lib_dir, module_name + '.so')
code = 'some code'
have_module = os.path.isfile(module_path)
if not have_module:
pyx_file = os.path.join(lib_dir, module_name + '.pyx')
# THIS IS WHERE EACH PROCESS TRIES TO WRITE TO THE FILE. THE CODE HERE
# PREVENTS A RACE CONDITION.
try:
fd = os.open(pyx_file, os.O_CREAT | os.O_EXCL | os.O_WRONLY)
except OSError as e:
if e.errno == errno.EEXIST:
pass
else:
raise
else:
os.fdopen(fd, 'w').write(code)
# THIS IS WHERE EACH PROCESS TRIES TO READ FROM THE FILE. CURRENTLY THERE IS A
# RACE CONDITION.
module = imp.load_dynamic(module_name, module_path)
(上面部分代码是从this answer借来的。)
当同时运行多个进程时,此代码只会打开一个进程并写入pyx_file(假设pyx_file 尚不存在)。问题是,当这个进程正在写入pyx_file 时,其他进程会尝试加载pyx_file——在后面的进程中会出现错误,因为在它们读取pyx_file 时,它是不完整的。 (具体来说,ImportErrors 被引发,因为进程正在尝试导入文件的内容。)
避免这些错误的最佳方法是什么?一个想法是让进程在一个while循环中不断尝试导入pyx_file,直到导入成功。 (这个解决方案似乎不是最理想的。)
【问题讨论】:
标签: python io race-condition python-import python-os