Perl fork为什么没有回车符/换行符会破坏代码?

时间:2014-08-29 17:58:33

标签: perl loops printing fork

任何人都可以告诉我这个代码为什么能顺利运作的神秘面纱:

#!/usr/bin/perl

my $papa = $$;
my $pid;
$pid = fork;
die "Fork call has failed: $!" unless defined $pid;

if ($pid) {
    # Dad code
    while (1) {
        print "Fix your room Charlie\n";
        sleep(1);
    }

} else {
    # Child code
    for ( my $count = 0; $count < 5; $count++ ) {
        print "Oh, not now dad...\n";
        sleep(1);
    }
    local $SIG{TERM} = "IGNORE";
    kill TERM => -$papa;
    exit;
}

但如果我将跳跃移到下一行它突然没有?

#!/usr/bin/perl

my $papa = $$;
my $pid;
$pid = fork;
die "Fork call has failed: $!" unless defined $pid;

if ($pid) {
    # Dad code
    while (1) {
        print "Fix your room Charlie";
        sleep(1);
    }

} else {
    # Child code
    for ( my $count = 0; $count < 5; $count++ ) {
        print "Not now dad...\n";
        sleep(1);
    }
    local $SIG{TERM} = "IGNORE";
    kill TERM => -$papa;
    exit;
}

这可能是非常愚蠢的事情,或者我有一个理由可以帮助我更好地理解印刷品的内部......或者叉子的内部 (我知道,一个孩子杀死它的父亲并不好,但请注意父亲已进入无限循环)

提前致谢:)

2 个答案:

答案 0 :(得分:3)

您的问题归结为以下几点:

$ perl -e'print "FOO\n"; kill TERM => $$'
FOO
Terminated

$ perl -e'print "FOO";   kill TERM => $$'
Terminated

You're suffering from buffering.

当连接到终端时,STDOUT是行缓冲的。这意味着当输出换行符,缓冲区变满并且正常退出时,它将刷新。在第一个程序中,这是在发送信号之前发生的。在后者中,发送信号后会发生这种情况。

明确刷新输出

$ perl -e'print "FOO"; select->flush(); kill TERM => $$'
FOOTerminated

或者导致为每个print

刷新输出
$ perl -e'$|=1; print "FOO"; kill TERM => $$'
FOOTerminated

答案 1 :(得分:2)

You're suffering from buffering.

设置$OUTPUT_FLUSH以确保打印在输出前不等到换行符:

local $| = 1; # Flush output

# Dad code
while (1) {
    print "Fix your room Charlie";
    sleep(1);
}