【问题标题】:Why aren't buffers auto-flushed by default?为什么默认情况下不自动刷新缓冲区?
【发布时间】:2011-09-13 16:13:31
【问题描述】:

我最近有幸在我的 Perl 脚本中设置了$| = 1;,以帮助它通过管道更快地与另一个应用程序通信。

我很好奇为什么这不是默认设置。换句话说,如果我的缓冲区被立即刷新,我会失去什么?

【问题讨论】:

  • 更快?不,可能不会,因为它会更频繁地被唤醒。不过,它的延迟会更低。
  • 我经常希望如此。我不相信这种好处值得它所带来的所有麻烦。

标签: perl buffer autoflush


【解决方案1】:

写入文件描述符是通过系统调用完成的,系统调用很慢。

缓冲一个流并仅在写入一定数量的数据后刷新它是一种节省一些系统调用的方法。

【讨论】:

  • 还有数据包。和磁盘写入。而且......几乎所有可以更好地一次处理超过几个字节数据的东西:)
【解决方案2】:

对它进行基准测试,你就会明白。

缓冲取决于输出句柄的设备类型:ttys是行缓冲的;管道和套接字是管道缓冲的;磁盘是块缓冲的。

这只是基本的编程。这不是 Perl 的东西。

【讨论】:

    【解决方案3】:

    I/O 缓冲区刷新的次数越少,您的代码通常就越快(因为它不必经常进行系统调用)。因此,通过启用自动刷新,您的代码会花费更多时间等待 I/O。

    在纯网络 I/O 驱动的应用程序中,这显然更有意义。但是,在最常见的用例中,行缓冲 I/O(Perl 对 TTY 的默认设置)允许程序不那么频繁地刷新缓冲区并花更多时间做 CPU 工作。一般用户不会注意到终端或文件中的差异。

    【讨论】:

    • 因此,换句话说,如果我期望通过管道有连续的数据流,那么自动刷新是有意义的,因为代码不会等待太多。我说对了吗?
    • 不,只需一次发送所有标题。对它们进行行缓冲并不重要。一切总是读取所有的标题。
    • 在每个标题换行符之后刷新而不是仅在末尾的双换行符处刷新如何更好?
    • User-Agent 这样的大型 HTTP 标头行只有大约 120 个字节。短行可能少于 20 个字节。对于典型的 MTU,20 多个 HTTP 标头行应该很容易放入一个数据包中。如果您对 HTTP 标头进行行缓冲,大多数网络堆栈将每行吐出一个数据包。导致 TCP/IP 开销增加 20 倍。 HTTP 是不应进行行缓冲的协议的完美示例,而 IRC 是同样应进行行缓冲的协议的完美示例。
    猜你喜欢
    • 2020-04-06
    • 2018-04-17
    • 2021-08-31
    • 2021-09-16
    • 1970-01-01
    • 2013-12-08
    • 2011-08-26
    • 2022-10-02
    • 1970-01-01
    相关资源
    最近更新 更多