Python何时将文件写入磁盘?

时间:2013-05-29 20:21:34

标签: python file unix file-io operating-system

我有一个与配置文件交互的库。导入库时,初始化代码会读取配置文件,可能会对其进行更新,然后将更新的内容写回文件(即使没有更改)。

偶尔会遇到配置文件内容消失的问题。具体来说,当我运行多个短脚本调用(使用库),背靠背,数千次时会发生这种情况。它永远不会发生在同一个目录中,这让我相信这是一个有点随机的问题 - 特别是IO的竞争条件。

这是一个很难调试,因为我永远无法可靠地重现问题,它只发生在某些系统上。我对可能发生的事情有所怀疑,但我想知道我的Python文件I / O图片是否正确。

所以问题是, Python程序何时实际将文件内容写入磁盘?我认为在文件关闭时内容将会转到磁盘,但我可以解释这个错误。当python关闭文件时,它是将内容刷新到磁盘本身,还是简单地将其排队到文件系统? Python终止后是否可以将文件内容写入磁盘?我可以使用fp.flush(); os.fsync(fp.fileno())(其中fp是文件句柄)来避免此问题吗?

如果重要,我正在Unix系统上编程(特别是Mac OS X)。 修改:另外,请记住,这些进程并未同时运行。

附录:这是我怀疑的具体竞争条件:

  1. 调用进程#1。
  2. 进程#1以读取模式打开配置文件,完成后将其关闭。
  3. 进程#1以写入模式打开配置文件,删除其所有内容。擦除内容将同步到磁盘。
  4. 进程#1将新内容写入文件句柄并关闭它。
  5. 进程#1:关闭文件后,Python告诉操作系统将这些内容写入磁盘的队列。
  6. 流程#1关闭并退出
  7. 调用流程#2
  8. 进程#2以读取模式打开配置文件,但新内容尚未同步。进程#2看到一个空文件。
  9. 在进程2读取文件
  10. 后,操作系统最终完成将内容写入磁盘
  11. 进程#2,认为文件为空,设置配置文件的默认值。
  12. 进程#2将其配置文件的版本写入磁盘,覆盖最后一个版本。

1 个答案:

答案 0 :(得分:1)

几乎可以肯定不是python的错。如果python关闭文件,OR会干净地退出(而不是被信号杀死),那么操作系统将拥有该文件的新内容。任何后续打开都应返回新内容。必须有更复杂的事情发生。这是一些想法。

  1. 您所描述的内容听起来比Python错误更容易成为文件系统错误,并且文件系统错误不太可能发生。

  2. 如果您的文件实际驻留在远程文件系统中,则文件系统错误更有可能发生。他们呢?

  3. 所有进程都使用同一个文件吗?在文件上执行“ls -li”以查看其inode编号,并查看它是否发生了变化。在您的方案中,它不应该。有可能某些东西正在移动文件,移动目录,或删除目录并重新创建它们吗?是否涉及符号链接?

  4. 您确定程序的运行没有重叠吗?它们中的任何一个是从带有“&”的shell运行的在最后(即在后台)?这很容易意味着在第一个完成之前就开始了第二个。

  5. 是否还有其他程序写入同一文件?

  6. 这不是你的问题,但如果你需要进行原子更改(以便任何并行运行的程序只能看到旧版本或新版本,而不是空文件),实现它的方法是将新内容写入另一个文件(例如“foo.tmp”),然后执行os.rename(“foo.tmp”,“foo”)。重命名是原子的。