我正在编写一个多线程程序,该程序需要用以下bash行终止:
killall -QUIT -w procname
我决定使用一个线程来接收一些需要处理的信号,比如SIGQUIT和SIGUSR1,而忽略其他线程中的SIGQUIT。
忽略我写下的信号:
struct sigaction s;
s.sa_handler=SIG_IGN;
if((sigaction(SIGQUIT,&s,NULL))==-1) {
perror("sigaction");
return -1;
}
我在指定等待信号的线程中写入下面的代码(HANDLRNO是一个检查ErrNO和Exchange的函数):
sigset_t threadset;
int err, sig;
if(sigfillset(&threadset)==-1) handlerrno("Sigfillset thread stats");
if(sigdelset(&threadset,SIGQUIT)==-1) handlerrno("Sigdelset thread stats");
if(sigdelset(&threadset,SIGINT)==-1) handlerrno("Sigdelset thread stats");
if(sigdelset(&threadset,SIGTERM)==-1) handlerrno("Sigdelset thread stats");
if(sigdelset(&threadset,SIGUSR1)==-1) handlerrno("Sigdelset thread stats");
if((err=pthread_sigmask(SIG_SETMASK,&threadset,NULL))!=0)
handlerror(err,"Set sigmask thread stats");
if((err=sigwait(&threadset,&sig))!=0) handlerror(err,"Sigwait");
//I handle the signals here
但是,当我从shell启动SIGQUIT时,指定等待信号的线程似乎被卡在sigwait()中,所以我不知道发生了什么,以及哪个线程获得了信号。
密码有问题吗?谢谢您!
最佳答案
忽略掩码是进程范围的。在sigaction
调用之后,SIQUIT
在任何线程中都不会成为挂起的,因此sigwait
将永远阻塞。
您应该做的是在创建任何线程之前阻塞主线程中的信号,以便子线程也阻塞它(child threads inherit the signal mask of their parent thread)。
处理线程应该能够在信号被阻塞的情况下将其出列。
(我不确定你选择的终止信号是否正确。SIQUIT
通常通过Ctrl+\
发送,并在终止前创建核心转储。或许SIGTERM
会是更好的选择。)
关于c - 用sigwait处理SIGQUIT,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45507747/