以不同的方式处理信号

任何人都可以帮助我理解以下三种处理信号的方式之间有什么区别? 我在C的客户端/服务器上运行。

编辑:我明白,第一个例子是错误的,现在我想知道哪个更好/可能,第二个是第三个? 我还在网络上看到有人在他们之间进行混合,使用“sigemptyset”和“sigaddset”中的“struct sigaction sig”,没有任何sigprocmask。 这比我的解决方案好吗?

处理器:

void closeSig(){
    close(socketAccept);
    close(socket);
    exit(1);
}

第一个例子:

signal(SIGINT, closeSig);

第二个例子:

sigset_t set;
struct sigaction sig;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sig.sa_sigaction = &closeSig;
sig.sa_flags = SA_SIGINFO;
sig.sa_mask = set;
sigaction(SIGINT, &sig, NULL);
sigprocmask(SIG_UNBLOCK, &set, NULL);

第三个例子:

struct sigaction sig;
sig.sa_sigaction = &closeSig;
sig.sa_flags = SA_SIGINFO;
sigaction(SIGINT, &sig, NULL);

根据POSIX sigaction()closeSig()函数不是严格适用于信号的回调函数。 它应该是:

void closeSig(int signum);

对于常规的回调,但是当您使用SA_SIGINFO ,它需要:

void closeSig(int signum, siginfo_t *info, void *context);

您还需要查看sigprocmask()的POSIX规范。

我们来看第二个例子:

sigset_t set;
struct sigaction sig;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sig.sa_sigaction = &closeSig;
sig.sa_flags = SA_SIGINFO;
sig.sa_mask = set;
sigaction(SIGINT, &sig, NULL);
sigprocmask(SIG_UNBLOCK, &set, NULL);

& on &closeSig是不必要的,但是无害。 但是,问题中显示的closeSig()类型是错误的。 sigset_t表示在调用中断处理程序时SIGINT (仅)将被阻止,但由于标志不包含SA_NODEFER ,因此无论如何都会发生。 所以,对于sigaction() ,代码处理set是多余的。

sigprocmask()的调用将阻止中断( SIGINT )。 目前尚不清楚为什么要这样称呼; 必须先前调用sigprocmask()来阻止中断才能发挥作用。 但是,在此之后,如果中断被发送到进程, closeSig()函数将被调用,它不会期望的参数。

第三个例子是:

struct sigaction sig;
sig.sa_sigaction = &closeSig;
sig.sa_flags = SA_SIGINFO;
sigaction(SIGINT, &sig, NULL);

这与解析和简化第二个例子中描述的最小操作非常接近。 主要问题是sig.sa_mask被设置为不确定的值。 代码应该是:

struct sigaction sig;
sig.sa_sigaction = &closeSig;
sig.sa_flags = SA_SIGINFO;
sigemptyset(&sig.sa_mask);
sigaction(SIGINT, &sig, NULL);

现在这相当于第二个例子。

链接地址: http://www.djcxy.com/p/80299.html

上一篇: Handling signals in different ways

下一篇: About catching the SIGSEGV in multithreaded environment