2016-04-30 50 views
7

我有以下问题,我已在这两个迷你Perl脚本中重新构建。 这是主要的脚本:在关闭文件句柄时向Perl脚本发送信号

#!/usr/bin/perl 
$SIG{INT} = \&signal_handler_one; 
open(my $pipe, "|-", "/home/pa/Desktop/POC2"); 
close $pipe; 
sub signal_handler_one{ 
    print "This is expected to print\n"; 
} 

在第三行它会打开一个管道,这个脚本:

#!/usr/bin/perl 
$SIG{INT} = \&signal_handler_two; 
sleep(10); 
sub signal_handler_two{ 
    print "This isn't expected to print\n"; 
} 

的问题是,当我开始了第一个脚本,然后发送SIGINT给它,而它正在关闭第4行的管道,signal_handler_two被触发而不是signal_handler_one。为什么它的行为如此?有没有办法解决这个问题(我的目标是让signal_handler_one执行)。

编辑: 我最初使用Ctrl + C在终端上发送信号,导致打印出“This is not expected to print”。但是当我使用kill从另一个终端向父进程发送信号时,它只是忽略它。

编辑2: 我终于解决它不使用开放拿到管,而是由人工分叉execing然后等待孩子而不是仅仅调用接近 。现在一切似乎都很好。看起来这种行为是特定于我的环境的,但如果任何人都能重现同样的错误,请告诉我。

+1

所以第二个脚本是'POC2'?你如何发送信号?你怎么知道它是在第一个脚本关闭管道的时候? – Borodin

+0

我通过终端上的Ctrl + C发送它。关闭呼叫阻塞,直到第二个过程终止,因此我有10秒的时间窗口让我在正确的时间发送Ctrl + C。是的,POC2是第二个剧本。 – Void

+1

我想你会发现Ctrl-C将信号发送到最近激活的进程。你可以更具选择性地让第一个程序用'print'$$ \ n“'来报告PID,然后在命令行上用'kill -s INT 1234'报告,用实际的PID替换'1234' – Borodin

回答

3

我无法重现您正在观察的行为。当我在终端按CTRL-C,两个子和父立即接收SIGINT

use diagnostics; 
use feature qw(say); 
use strict; 
use warnings; 

$SIG{INT} = sub { say "This is expected to print"; die }; 
my $pid = open (my $pipe, "|-", "script.pl"); 
say "PID = $pid"; 
eval { 
    say "Closing.."; 
    my $close_ok = close $pipe; # Note "close" here waits for child to exit 
    if (! $close_ok) { 
     say "Error closing: $!"; 
    } 
    else { 
     say "Close done."; 
    } 
}; 
if ([email protected]) { 
    say "Parent caught SIGINT."; 
} 

其中script.pl是:

#! /usr/bin/env perl 

use feature qw(say); 
use strict; 
use warnings; 

$SIG{INT} = sub { die }; 
eval { 
    say "Sleeping.."; 
    for (1..5) { 
     sleep 1; 
     say $_; 
    } 
}; 
if ([email protected]) { 
    say "Child caught SIGINT."; 
    exit; 
} 

在Ubuntu在终端运行第一程序(gnome-terminal的输出16.04)是:

PID = 1746 
Closing.. 
Sleeping.. 
1 
2 
^CThis is expected to print 
Child caught SIGINT. 
Parent caught SIGINT. 
Uncaught exception from user code: 
    refcnt: fd -1 < 0 

请注意,有一个未捕获的异常refcnt: fd -1 < 0。我不知道那是什么。也许是因为close没有成功?

+0

我想那时我的环境有问题。如果我执行你的代码,它不会打印“Parent caught SIGINT。”。 – Void

+0

@Void,不,你的环境是正确的。您看不到“Parent”行,因为您在'close' [忽略SIGINT]期间发送了SIGINT(http://stackoverflow.com/a/4719492/132382)。这个答案做了一些不同的事情 - 发送SIGINT太早或太迟,例如, – pilcrow

+0

@pilcrow我确信我在'关闭'期间发送信号。你可以在输出中看到它说'Closing..',然后等待程序退出。这必须发生在'close'内部,因为'close'后面的print语句没有显示。5秒后,如果我没有按'CTRL-C','close'将会返回。这就是我如何解释输出。我很好奇为什么你的意思是它在'close'期间不发送'SIGINT'? –

相关问题