2014-08-29 43 views
1

任何人都可以賜教一下爲什麼這個代碼工作順利大有玄機:Perl 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; 
} 

這可能是一些非常愚蠢的,或者是我有充分的理由,這將有助於我更好地瞭解打印的內件...或叉 (我知道的內件,一個孩子殺死其父親是不是很好,但要注意的父親已經進入了一個無限循環)

感謝提前:)

回答

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 
相關問題