与调用sigwait
问题描述:
我正在写一个多线程程序,需要使用以下的bash行终止处理SIGQUIT SIGUSR1,并忽略其他SIGQUIT。 要忽略我写了这个信号:与调用sigwait
struct sigaction s;
s.sa_handler=SIG_IGN;
if((sigaction(SIGQUIT,&s,NULL))==-1) {
perror("sigaction");
return -1;
}
我写在指定的等待信号(handlerrno是检查errno和退出功能)线程以下代码:
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
会是一个更好的选择。)
谢谢!我需要终止这样的过程,因为这是大学的任务,所以我们的老师给了我们一个测试脚本,以确保代码的工作。 无论如何,问题在于处理线程是由主线程产生的,所以如果我在那里阻塞处理线程,它也会阻止它? – Gixuna
正确。如果没有线程解除阻塞,并且在进程中只有一个sigwait调用处于活动状态,那么sigwait调用应该会得到它。 – PSkocik
它的工作,非常感谢! – Gixuna