为什么我的perl守护进程不能打印?
问题描述:
我正在调试一个守护进程,我试图使用print
语句将信息输出到终端。我的代码的要点是:为什么我的perl守护进程不能打印?
#!/usr/bin/env perl
use strict;
use warnings;
use Readonly;
Readonly my $TIMEOUT => ...;
...
while (1) {
print "DEBUG INFO";
...
sleep $TIMEOUT;
}
但是,没有输出它打印到我的终端。为什么是这样?
答
摘要:
使用$| = 1
或换行,"\n"
添加到打印。
说明:
这不是打印到终端的原因是因为Perl正在缓冲对效率的输出。一旦打印缓冲区被填满,它将被刷新并且输出将出现在您的终端中。您可能希望强制冲洗缓冲区,因为根据您的输出长度,您可能会等待相当长的时间!
主要有两种方法来刷新缓冲区:
1)当你打印到你的终端,那么你的文件句柄是最有可能STDOUT
。把手附连到终端的任何文件都默认在行缓冲模式,我们可以刷新缓冲区,并通过添加一个新行字符到您print
语句强制输出:
while (1) {
print "DEBUG INFO\n";
...
sleep $TIMEOUT;
}
2)第二种方法是使用$|
,当设置为非零时,使当前文件句柄(默认为STDOUT
或最后为select
ed)热并立即强制刷新缓冲区。因此,以下也将迫使调试信息打印:
$| = 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,这给了伟大的洞察为什么我们有缓冲并解释如何打开和关闭它。
守护进程的STDOUT通常有目的地指向终端以外的某个地方。你是如何守护程序的? – ikegami