2012-05-17 95 views
3

我已經寫了下面這段代碼來測試孩子和父母之間的信號。理想情況下,當孩子給父母提供一個SIGINT時,父母應該返回新的迭代並等待用戶輸入。這是我在perl 5.8中觀察到的,但是在perl 5.6.1(我被要求使用)中父母實際上是「被殺死」的。沒有下一個迭代。perl - 子進程發信號父母

my $parent_pid = $$; 
$pid = fork(); 
if($pid == 0) 
{ 
    print "child started\n"; 
    kill 2, $parent_pid; 
} 
else 
{ 
    while(1) 
    { 
     eval 
     { 
      $SIG{INT} = sub{die "GOTCHA";}; 
      print 'inside parent'."\n"; 
      $a = <>; 
     }; 
     if([email protected]) 
     { 
       print "got the signal!!!!\[email protected]\n"; 
       next; 
     } 
    } 

} 

有人請給出一個解決這個問題或其他方式的信號,以便它進入新的迭代。

+0

Sry基因,不能重現它。 – int2000

+0

Windows還是不行? – ikegami

+0

@ikegami windows它是 –

回答

3

5.6.X上的失敗可能是因爲Perl用來處理信號的方式,這是用'Safe Signal Handling' in Perl 5.8.0修復的。無論哪種情況,您都在使用一個實際上是考古學的Perl,並且您應該強烈地向您的主人辯稱,您應該至少使用Perl 5.12,最好是5.14。

+0

也許你是對的...但有很多的依賴關係。 –

2

這可能是一個競爭條件,由孩子在父母準備好之前發送SIGINT引起的。請記住,在您使用fork()後,您將擁有兩個獨立的進程,每個進程都可以以任何喜歡的速度進行。

在您的情況下,最好在fork()調用之前設置SIGINT處理程序,因此您知道它在孩子嘗試kill()其父母之前肯定已到位。

(有一些小的修改):

$SIG{INT} = sub { die "GOTCHA" }; 

my $parent_pid = $$; 
defined(my $pid = fork()) or die "Cannot fork() - $!"; 

if($pid == 0) 
{ 
    print "child started\n"; 
    kill INT => $parent_pid; 
} 
else 
{ 
    while(1) 
    { 
     eval 
     { 
      print "inside parent\n"; 
      <>; 
     }; 
     if([email protected]) 
     { 
      print "got the signal!!!!\[email protected]\n"; 
      next; 
     } 
    } 
} 
+0

在嘗試不同的事情時,我通過適當地使用'睡眠'來確保沒有競爭條件。無論如何,這可能是原因。 –