为什么这里需要POSIX :: SigSet?

时间:2013-08-21 14:40:47

标签: linux perl signals posix

!/usr/bin/env perl
use POSIX;

my $sig_set = POSIX::SigSet->new(POSIX::SIGINT);
my $sig_act = POSIX::SigAction->new(sub { print "called\n"; exit 0 },$sig_set);

POSIX::sigaction(SIGINT,$sig_act);

sleep(15);

如果我已经告诉POSIX::SigSet我想要POSIX::sigaction,我为什么需要使用SIGINT

基本上我正在尝试用我的coderef响应我添加到SigSet的每个信号,看POSIX::sigaction签名,它必须接受一个信号作为第一个参数,如果我不合理已经告诉POSIX::SigAction我的POSIX::SigSet

我确定我在这里遗漏了一些东西。

感谢,

1 个答案:

答案 0 :(得分:6)

您问题的答案

在执行信号处理程序子程序期间,POSIX :: SigSet指定屏蔽(忽略)的附加信号。它对应于传递给C version of sigaction的基础结构的sa_mask成员。

现在,除非您通过SA_NODEFER明确请求,否则SIGINT(以及sigaction的第一个参数)将被默认屏蔽掉。

更好的方法?

但是,如果只想注册一个信号处理程序,执行程序不会被注册的信号中断(例如,在SIGINT处理程序中不允许SIGINT),你可以跳过POSIX模块完全:

$SIG{INT} = sub { print "called\n"; exit 0; };  # Won't be interrupted by SIGINT

在可能的情况下,Perl的信号调度模拟了在处理程序执行期间阻塞信号的传统UNIX语义。 (在Linux上,它当然可以.sigprocmask()在执行处理程序之前被调用,然后注册作用域保护功能以在用户提供的子类的末尾重新允许该信号。)