【问题标题】:Abort a slow flush to disk after write?写入后中止缓慢刷新到磁盘?
【发布时间】:2011-01-28 08:29:50
【问题描述】:

有没有办法以操作系统不认为有必要将未写入的数据刷新到磁盘的方式中止 python 写入操作?

我正在将数据写入 USB 设备,通常为数兆字节。我在写入时使用 4096 字节作为我的块大小,但似乎 Linux 很早就缓存了一堆数据,然后慢慢将其写入 USB 设备。如果在写入过程中的某个时刻,我的用户决定取消,我希望应用程序立即停止写入。我可以看到数据停止从应用程序流出和 USB 活动指示灯停止闪烁之间存在延迟。几秒钟,通常最多约 10 秒钟。我发现该应用程序正在使用 close() 方法,我假设,等待操作系统完成写入缓冲数据。每次写入后我都会调用 flush() ,但这似乎对延迟没有任何影响。我已经搜索了 python 文档以寻找答案,但一无所获。

【问题讨论】:

  • 这完全取决于操作系统和文件系统。 “正确”的行为(在正常的异步挂载下)是 close() 立即返回;如果您明确地使用 fdatasync(),它应该只等待刷新。您不太可能找到一种可移植的方式来改变这种行为,因为它会因系统而异。 (从 XP 左右开始,默认情况下,Windows 甚至根本不会将缓存写入 USB 驱动器。)

标签: python linux file-io flush


【解决方案1】:

它在某种程度上取决于文件系统,但在某些文件系统中,如果您在分配(全部)文件之前删除文件,则写入块的 IO 将永远不会发生。如果您截断它以便将仍在写入的部分切掉,这也可能是正确的。

如果您仍想访问数据,不确定是否真的可以中止写入。此外,支持此功能的文件系统类型(例如 xfs、ext4)通常不会在 USB 记忆棒上使用。

如果要将数据刷新到磁盘,请使用 fdatasync()。仅仅将 IO 库的缓冲区刷新到操作系统中不会实现任何物理刷新。

【讨论】:

    【解决方案2】:

    假设我理解正确,您希望能够“中止”而不是刷新数据。这可以使用 ctype 和一点点扑克。这非常依赖于操作系统,所以我会给你 OSX 版本,然后你可以做些什么来将其更改为 Linux:

    f = open('flibble1.txt', 'w')
    f.write("hello world")
    import ctypes
    x = ctypes.cdll.LoadLibrary('/usr/lib/libc.dylib')
    x.close(f.fileno())
    try:
      del f
    catch IOError:
      pass
    

    如果您将 /usr/lib/libc.dylib 更改为 Linux 的 /usr/lib 中的 libc.so.6,那么您应该可以继续使用了。基本上通过调用 close() 而不是 fclose(),不会调用 fsync(),也不会刷新任何内容。

    希望有用。

    【讨论】:

    • Lee,这看起来应该可以,但是,我无法获得所需的行为。我调用了 x.close(f.fileno()),它仍然执行刷新,阻塞 close() 调用,就像 python close() 命令一样。
    • 如果发生这种情况,那么 .close() 实际上并没有被调用。您可以通过检查返回码进行检查。如果你得到 None 或一个数字,它就不起作用 - 如果你得到 0(零),那么它就起作用了。
    【解决方案3】:

    当您中止写入操作时,尝试在关闭之前执行file.truncate(0);

    【讨论】:

      猜你喜欢
      • 2021-11-06
      • 2010-09-15
      • 2010-09-10
      • 1970-01-01
      • 1970-01-01
      • 2013-08-21
      • 2019-01-09
      • 2015-07-03
      • 1970-01-01
      相关资源
      最近更新 更多