5
!/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.

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

谢谢,

4

1 回答 1

6

你的问题的答案

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

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

更好的方法?

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

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

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

于 2013-08-21T14:54:49.967 回答