当我使用sleep时,为什么不在循环的每次迭代中打印输出?

时间:2011-07-02 17:52:11

标签: perl buffering

今天在我的大学里,老师问我一个问题。他在纸上写下了这段代码并说 “这段代码的输出是什么?”

use warnings;

for (1 .. 20)
{
    print ".";
}

我发现它很容易并且说它将循环20次,并且在每次迭代时它将打印一个点(。),因此总共20个点将是输出。

他说你是对的,然后他对代码做了一些修改。代码是:

use warnings;

for (1 .. 20)
{
    print ".";
    sleep 1;
}

他说现在输出的是什么?我不知道睡眠功能,我猜想在每次迭代时它会打印点(。)然后它会等待1秒(因为睡眠功能)然后它会再次迭代然后它会再次打印(。)然后它将等待1秒,依此类推......

老师叫我在家里检查一下。我在家尝试了,我发现第二个代码等了20秒,然后一次打印所有点(20个点)。我想知道这是怎么发生的?为什么点(。)在每次迭代时都没有打印?

3 个答案:

答案 0 :(得分:24)

真正的问题与sleep无关,而是............

您是Suffering from Buffering 。所提供的链接将带您阅读大约1998年由Perc Journal撰写的优秀文章,来自Marc Jason Dominus(高阶Perl的作者)。这篇文章可能已有十多年的历史了,但今天的主题和他写这篇文章的时候一样重要。

其他人已经解释了$| = 1;技术。我想补充一点,在Perl社区的主要思想中,似乎$| = 1优于$|++只是因为它的含义更清晰。我知道,自动增量也非常简单,但是当$|++被应用时,每个看过代码的人都会知道--的行为(而不是在use strict; use warnings; { local $| = 1; for ( 1 .. 20 ) { print '.'; sleep 1; } } 查找3}})。我碰巧也喜欢本地化Perl的“特殊变量”的任何修改,以便效果不会冲到代码的其他部分,这些部分可能对默认的Perl行为的特定更改不起作用。既然如此,我会把它写成:

{{1}}

答案 1 :(得分:15)

Perl和许多其他程序,默认情况下是行缓冲输出。如果需要无缓冲输出,可以将$|设置为1

答案 2 :(得分:12)

它没有清除缓冲区。如果print语句末尾有换行符,它将自动为您执行此操作:

use warnings;

for (1 .. 20) {
    print ".\n";
    sleep 1;
}

如果你不想要换行符(我不认为你这样做),你可以使用特殊的autoflush变量$|。尝试将其设置为1或递增它。

use warnings;

$|++;

for (1 .. 20) {
     print ".";
     sleep 1;
}