我正在编写一个多线程程序,该程序需要用以下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/

10-11 18:03