忽略一个信号并告诉它在Perl中什么也不做的区别是什么?

6 perl signals

如果我告诉Perl明确忽略一个信号,SIGINT没有效果:

$SIG{INT} = 'IGNORE';
my $count = 0;
say $count++ and sleep 1 while 1;
Run Code Online (Sandbox Code Playgroud)

然后按Control-C显然没有效果.另一方面,如果我告诉它什么都不做:

$SIG{INT} = sub { };
my $count = 0;
say $count++ and sleep 1 while 1;
Run Code Online (Sandbox Code Playgroud)

然后按Control-C有效!它从sleep()调用中唤醒程序并立即递增计数.忽略信号并告诉它什么都不做之间的区别是什么?

在我的程序中,我想让代码在SIGINT上运行,而不会破坏任何东西.我想要的东西:

$SIG{INT} = sub { say "Caught SIGINT!"; return IGNORED; };  # runs without disrupting sleep
Run Code Online (Sandbox Code Playgroud)

pil*_*row 13

忽略信号并告诉它什么都不做之间的区别是什么?

传递信号时仍然会调用"不执行任何操作"处理程序,sleep在这种情况下会中断调用.另一方面,忽略的信号被系统简单地丢弃,对过程没有任何影响.

请参阅此处了解特定于C的更全面的参考.


Pet*_*acs 6

信号传递可以中断大量系统调用.通常,您可以检查$!(又名errno)是否存在EINTR并采取措施重新尝试失败的系统调用.

如果您的代码的某些部分(在这种情况下,您的调用sleep())不会中断POSIX::sigprocmask对您很重要,那么您可以在临界区中使用来阻止信号.应用程序收到的任何信号都将排队,直到您取消阻止它们为止,此时它们将被传递.我很确定当特定类型的多个信号被阻塞时会有一些有趣的语义(我认为它们可能合并成一个信号).

这是IBM关于重入函数的一个很好的入门,包括一些示例sigprocmask.


Mar*_*ahl 1

不知道为什么它没有按您的预期工作,但通常当我尝试完成类似的事情时,除了 INT 信号之外,我还会捕获 TERM 信号。