我有以下代码(为清楚起见已简化):
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)
(上面的一些代码是从此答案中借用的。)
一次运行多个进程时,此代码仅导致一个进程打开并写入pyx_file
(假定pyx_file
尚不存在)。问题在于,当该进程正在写入时pyx_file
,其他进程会尝试加载pyx_file
-在后者的进程中会引发错误,因为在读取时pyx_file
,它是不完整的。(特别ImportError
是,引发s,因为进程正在尝试导入文件的内容。)
避免这些错误的最佳方法是什么?一种想法是让进程继续尝试pyx_file
在while循环中进行导入,直到成功导入为止。(此解决方案似乎不是最优的。)
这样做的方法是每次打开时都使用排他锁。写入器在写入数据时会持有锁,而读取器会阻塞直到写入器通过fdclose调用释放锁。如果文件已被部分写入并且写入过程异常退出,那么这当然会失败,因此,如果无法加载模块,则会显示删除文件的适当错误:
import os
import fcntl as F
def load_module():
pyx_file = os.path.join(lib_dir, module_name + '.pyx')
try:
# Try and create/open the file only if it doesn't exist.
fd = os.open(pyx_file, os.O_CREAT | os.O_EXCL | os.O_WRONLY):
# Lock the file exclusively to notify other processes we're writing still.
F.flock(fd, F.LOCK_EX)
with os.fdopen(fd, 'w') as f:
f.write(code)
except OSError as e:
# If the error wasn't EEXIST we should raise it.
if e.errno != errno.EEXIST:
raise
# The file existed, so let's open it for reading and then try and
# lock it. This will block on the LOCK_EX above if it's held by
# the writing process.
with file(pyx_file, "r") as f:
F.flock(f, F.LOCK_EX)
return imp.load_dynamic(module_name, module_path)
module = load_module()
我想读一个属性文件,如下所示: 但当我尝试这样做时,我会出现一个错误: 线程“main”java中出现异常。lang.NullPointerException:inStream参数在java中为null。base/java。util。物体。java上的requirennoull(Objects.java:246)。base/java。util。财产。在majorbot加载(Properties.j
问题内容: 我必须阅读tomcat日志文件,并在一段时间(例如:一个小时)后再次读取该文件(仅针对新添加的内容),因此我创建了RandomAccessFile来记录我完成的最后一个位置并使用BufferedReader.readLine()方法。 但是,我发现有时我无法读取文件的整行。 例如,tomcat正在尝试编写以下内容(仅作为示例): 192.168.0.0本地主机/index.html .
问题内容: 我目前正在阅读“用困难的方式学习Python”,已经读到了第16章。 写入文件后,似乎无法打印文件的内容。它只是不打印任何内容。 问题答案: 你不调用函数和,而不是你只是得到他们的 指点 。由于它们是函数(或更准确地说,是方法),因此您需要在函数名称后调用它:。 那就是问题所在; 您以写入模式打开文件,该模式将删除文件的所有内容。您写入了文件,但从未关闭它,因此更改从未提交,文件保持为
我正在写一个小程序,可以处理大的(最多无限个)文本文件。处理过程将相当简单(将部分内容修剪并处理成单独的字符串,然后打印出来)。然而,由于数据的长度可能是无限的,我可能会遇到超过堆的问题。我想到的第一个解决方案是使用流来处理数据。然而,Files类中的lines()方法只能将文本分成行。我的线条也可以无限长! 我遇到的另一个解决方案是使用scanner useDelimiter方法: 这种方法会阻
在我的骆驼应用程序,它是进程文件从ftp服务器。当我测试时,我发现在文件上传期间,同时我的路线开始拾取该文件并做过程。我已经设置了readLock为“changed”,延迟为“60000”,我的文件大约是500M。我错过什么了吗?
当我的程序试图从XML配置文件中读取时,我收到以下错误: org.xml.sax.SAXParseException;systemId:file:/home/sara/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/poseidonwebservicewar_v12/config.xml;行号:74;