2012-05-17 94 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

在尝试不同的事情时,我通过适当地使用'睡眠'来确保没有竞争条件。无论如何,这可能是原因。 –