我有一个与配置文件交互的库。导入库时,初始化代码会读取配置文件,可能会对其进行更新,然后将更新的内容写回文件(即使没有更改)。
偶尔会遇到配置文件内容消失的问题。具体来说,当我运行多个短脚本调用(使用库),背靠背,数千次时会发生这种情况。它永远不会发生在同一个目录中,这让我相信这是一个有点随机的问题 - 特别是IO的竞争条件。
这是一个很难调试,因为我永远无法可靠地重现问题,它只发生在某些系统上。我对可能发生的事情有所怀疑,但我想知道我的Python文件I / O图片是否正确。
所以问题是, Python程序何时实际将文件内容写入磁盘?我认为在文件关闭时内容将会转到磁盘,但我可以解释这个错误。当python关闭文件时,它是将内容刷新到磁盘本身,还是简单地将其排队到文件系统? Python终止后是否可以将文件内容写入磁盘?我可以使用fp.flush(); os.fsync(fp.fileno())
(其中fp
是文件句柄)来避免此问题吗?
如果重要,我正在Unix系统上编程(特别是Mac OS X)。 修改:另外,请记住,这些进程并未同时运行。
附录:这是我怀疑的具体竞争条件:
答案 0 :(得分:1)
几乎可以肯定不是python的错。如果python关闭文件,OR会干净地退出(而不是被信号杀死),那么操作系统将拥有该文件的新内容。任何后续打开都应返回新内容。必须有更复杂的事情发生。这是一些想法。
您所描述的内容听起来比Python错误更容易成为文件系统错误,并且文件系统错误不太可能发生。
如果您的文件实际驻留在远程文件系统中,则文件系统错误更有可能发生。他们呢?
所有进程都使用同一个文件吗?在文件上执行“ls -li”以查看其inode编号,并查看它是否发生了变化。在您的方案中,它不应该。有可能某些东西正在移动文件,移动目录,或删除目录并重新创建它们吗?是否涉及符号链接?
您确定程序的运行没有重叠吗?它们中的任何一个是从带有“&”的shell运行的在最后(即在后台)?这很容易意味着在第一个完成之前就开始了第二个。
是否还有其他程序写入同一文件?
这不是你的问题,但如果你需要进行原子更改(以便任何并行运行的程序只能看到旧版本或新版本,而不是空文件),实现它的方法是将新内容写入另一个文件(例如“foo.tmp”),然后执行os.rename(“foo.tmp”,“foo”)。重命名是原子的。