If we use sigaction to define a signal handler, then why don't we need to reset the handler? If we do the use signal(sig_no,handler_func)
then we must reset it. Why is this?
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
void func(int sig)
{
printf("caught signal:%d\n",sig);
// Not needed to reset handler. Why?
}
int main()
{
struct sigaction sa;
sa.sa_handler=(void*)func;
sigaction(SIGRTMIN,&sa,NULL);
kill(0,SIGRTMIN);
kill(0,SIGRTMIN);
kill(0,SIGRTMIN);
}
Output:
[root@dhcppc0 signals]# ./a.out
caught signal:34
caught signal:34
caught开发者_JAVA技巧 signal:34 (3 times signal caught by same handler without resetting handler)
The real reason goes back to some decades ago. The original signal()
didn't rearm the handler. It also didn't restart interrupted system calls. The BSD guys decided to have a more "reliable" signal()
, so they changed that semantics.
Since System V and BSD behaviour was so different, the POSIX commitee decided to introduce a new system call, sigaction()
, with parameters to modify its behaviour. So the whole reason sigaction()
exists is to have signal using code that behaves the same across Unix variants.
(Note that the bahaviour of signal()
can change even when using the same libc, for instance, glibc uses BSD behaviour by default, and SYSV behaviour when _XOPEN_SOURCE is defined).
Unless you specify SA_RESETHAND
in the flags, the disposition isn't changed (and therefore doesn't need to be reset)
If you were to set sa.sa_flags = SA_RESETHAND
You'd need to reset it because the disposition would be reset to SIG_DFL
(which is what happens with signal()
)
Basically, the answer to your question is "Because that's how sigaction works. Its behavior is different than signal".
精彩评论