为什么我的 perl 守护进程不打印?

Why won't my perl daemon print?

我正在调试一个守护进程,我正在尝试使用 print 语句将信息输出到终端。我的代码的要点是:

#!/usr/bin/env perl

use strict;
use warnings;

use Readonly;

Readonly my $TIMEOUT => ...;

...

while (1) {

   print "DEBUG INFO";

   ...

   sleep $TIMEOUT;
}

但是,没有输出它打印到我的终端。这是为什么?

总结:

使用 $| = 1 或添加换行符,"\n" 打印。

解释:

没有打印到终端的原因是 perl 正在缓冲输出以提高效率。一旦打印缓冲区被填满,它将被刷新并且输出将出现在您的终端中。您可能需要强制刷新缓冲区,因为根据 $TIMEOUT 的长度,您可能需要等待相当长的时间才能输出!

刷新缓冲区有两种主要方法:

1) 当您打印到您的终端时,您的文件句柄很可能是 STDOUT。默认情况下,附加到终端的任何文件句柄都处于 行缓冲 模式,我们可以通过向 print 语句添加换行符来刷新缓冲区并强制输出:

while (1) {
    print "DEBUG INFO\n";
    ...
    sleep $TIMEOUT;
 }

2) 第二种方法是使用 $| ,当设置为非零时使当前文件句柄(默认为 STDOUT 或最后一个 selected)hot 并立即强制刷新缓冲区。因此,下面也会强制打印调试信息:

$| = 1;
while (1) {
    print "DEBUG INFO";
    ...
    sleep $TIMEOUT;
}

如果使用这样的语法令人困惑,那么您可以考虑:

use IO::Handle;
STDOUT->autoflush(1);

while (1) {
    print "DEBUG INFO";
    ...
    sleep $TIMEOUT;
}

在许多需要立即刷新缓冲区的代码示例中,您可能会看到 $|++ 用于使文件句柄变热并立即刷新缓冲区,而 --$| 用于生成文件-处理冷水并关闭自动冲洗。有关详细信息,请参阅这两个答案:

  • Perl operator: $|++; dollar sign pipe plus plus
  • How does --$| work in Perl?

如果您有兴趣了解有关 perl 缓冲区的更多信息,那么我建议您阅读 Suffering from Buffering,它深入了解了为什么我们有缓冲并解释了如何打开和关闭它。