【问题标题】:Why won't my perl daemon print?为什么我的 perl 守护进程不打印?
【发布时间】:2015-12-17 01:37:41
【问题描述】:

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

#!/usr/bin/env perl

use strict;
use warnings;

use Readonly;

Readonly my $TIMEOUT => ...;

...

while (1) {

   print "DEBUG INFO";

   ...

   sleep $TIMEOUT;
}

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

【问题讨论】:

  • 一个守护进程的 STDOUT 通常是有目的地定向到终端以外的地方。你是如何守护程序的?

标签: perl daemon


【解决方案1】:

总结:

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

说明:

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

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

1) 当您打印到终端时,您的文件句柄很可能是STDOUT。默认情况下,附加到终端的任何文件句柄都处于 line-buffered 模式,我们可以通过在 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 缓冲区的更多信息,那么我建议您阅读Suffering from Buffering,它可以很好地了解我们为什么要使用缓冲并解释如何打开和关闭它。

【讨论】:

    最近更新 更多