Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python何时将文件写入磁盘?_Python_File_Unix_File Io_Operating System - Fatal编程技术网

Python何时将文件写入磁盘?

Python何时将文件写入磁盘?,python,file,unix,file-io,operating-system,Python,File,Unix,File Io,Operating System,我有一个与配置文件交互的库。导入库时,初始化代码读取配置文件,可能会对其进行更新,然后将更新的内容写回该文件(即使没有任何更改) 偶尔,我会遇到配置文件内容消失的问题。具体地说,当我(使用库)背靠背、数千次地多次调用短脚本时,就会发生这种情况。它在相同的目录中从未出现过,这让我相信这是一个有点随机的问题——特别是IO的竞争条件 这是一个调试的痛苦,因为我永远无法可靠地重现问题,而且它只发生在一些系统上。我怀疑会发生什么,但我想看看我在Python中对文件I/O的描述是否正确 所以问题是,Pyth

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

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

这是一个调试的痛苦,因为我永远无法可靠地重现问题,而且它只发生在一些系统上。我怀疑会发生什么,但我想看看我在Python中对文件I/O的描述是否正确

所以问题是,Python程序什么时候真正将文件内容写入磁盘?我原以为文件关闭时内容会进入磁盘,但我无法解释这个错误。当python关闭一个文件时,它是将内容刷新到磁盘本身,还是只是将其排队到文件系统Python终止后文件内容是否可以写入磁盘?我可以使用
fp.flush()避免这个问题吗;os.fsync(fp.fileno())
(其中
fp
是文件句柄)

如果有关系的话,我是在Unix系统(特别是Mac OS X)上编程的编辑:另外,请记住这些进程不是同时运行的

附录:以下是我怀疑的具体比赛条件:

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

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

  • 您描述的内容听起来更像是文件系统错误而不是Python错误,文件系统错误也不太可能

  • 如果文件实际位于远程文件系统中,则文件系统错误的可能性更大。是吗

  • 所有进程都使用同一个文件吗?在文件上执行“ls-li”以查看其inode编号,并查看它是否曾经更改。在您的场景中,不应该这样做。是否可能有什么东西正在移动文件、移动目录或删除目录并重新创建它们?是否涉及符号链接

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

  • 是否有其他程序写入同一文件

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


  • 不,当Python关闭该文件时,该文件已刷新到磁盘。我认为进程#2打开文件的时间比您想象的要早。如果多个进程同时访问一个文件,并且至少有一个进程写入该文件,您必须同步这些进程以获得一致的结果。这与Python无关。即使操作系统没有将数据写入磁盘,它也会保证将文件内容返回到2。进程,只要它从python中清除,因为访问该文件的任何人都共享一个内存缓存。(除非您在未配置一致性的共享文件系统上的不同计算机上运行进程,或者存在覆盖文件的争用条件。)一种可能的问题是:只要使用
    'w'
    打开,内容就会被截断。如果另一个进程在再次写入之前读取它,它将是空的。@Missavor在进程1中添加一些调试,它将检查它生成的文件是否从不为空,将进程1和进程2之间的文件名关联起来,这样您就知道是哪个运行生成了错误的文件。我想这是我所希望的最佳答案。非常感谢。事实证明,一名实习生编辑了一个库函数来生成另一个Python子流程(使用相同的模块)。在我改变主意后,问题似乎消失了。这可能也解释了为什么问题只发生在实习生的电脑上。