【问题标题】:Does closing a file imply flushing in Perl under Unix/MS-Windows/MacOs?关闭文件是否意味着在 Unix/MS-Windows/MacOs 下的 Perl 中刷新?
【发布时间】:2014-02-20 02:50:34
【问题描述】:

我只是想知道为什么 Perl 中没有“刷新”功能。 “perldoc -f close”说

close 关闭与文件句柄关联的文件或管道, 冲洗 IO 缓冲区,并关闭系统文件描述符。

但是 Unix 联机帮助页“man 2 close”说:

成功关闭并不能保证数据已经 成功保存到磁盘,因为内核延迟写入。这并不常见 当流关闭时刷新缓冲区的文件系统。如果你 需要确保使用 fsync(2) 物理存储数据。 (它 此时将取决于磁盘硬件。)

现在,据我所知,Perl 中没有 fsync 函数。当然,Perl 的 close 可以调用 fsync()。但即便如此,“man 2 close”说它取决于硬件,我不知道其他操作系统会发生什么。因此我的问题。我想确保缓冲区已刷新。

【问题讨论】:

    标签: perl io flush


    【解决方案1】:

    Perl 的 close 和 C 的 fclose 一样,会将语言的 IO 库缓冲区刷新到操作系统。此时可以安全地终止应用程序。

    但是,这并不意味着文件已提交到磁盘。此时机器无法安全关闭。[1]就像您声称的段落所说,fsync 会让您更接近那个。请记住,您不仅要同步文件,还要同步其路径中的每个目录。

    fsync 可用作IO::Handle::sync。文件句柄继承自 IO::Handle,因此您可以简单地使用 $fh->sync。 (这需要在旧版本的 Perl 上使用 use IO::Handle;。)


    1. 拔出驱动器也不安全,尽管弹出介质是安全的。操作系统将在允许弹出之前完成其写入。

    【讨论】:

    • 谢谢。所以这个故事的寓意是,作为一个程序员,你永远不能完全确定你的数据在磁盘上是安全的,除非你卸载设备?如果您是一名数据库程序员,并且必须 100% 确定某些内容已永久保存在磁盘上,该怎么办?例如,客户的订单?
    • @ubuplex 唯一可以完全确定地确保从物理驱动器硬件开始对整个 I/O 堆栈进行全面审计的方法;每一层都有缓存机制。有关该主题的更详细讨论,请参阅postgresql.org/docs/current/static/wal-reliability.html
    【解决方案2】:
    1. Perl 中的 close 函数与 C 中的 close 函数不同。Perl 做出某些保证,它的 C 对应物可能不会做出(尽管在这件事上,它没有)。

    2. 关于 C 的 close 行为的引用是在谈论磁盘(或通常:物理持久存储介质)。即使从程序员的角度来看,数据是逻辑上保存到文件系统的,但数据可能仍然物理上在操作系统缓冲区(即 RAM)中。除非您尝试在写入后立即移除物理介质,否则这无关紧要。

    【讨论】:

      猜你喜欢
      • 2013-07-18
      • 1970-01-01
      • 1970-01-01
      • 2019-05-28
      • 2016-05-18
      • 1970-01-01
      • 1970-01-01
      • 2014-08-15
      • 1970-01-01
      相关资源
      最近更新 更多