在我的程序中,我希望线程A定期向线程B发送SIGUSR1
。在线程B中,它将在sigwait
处阻塞。至于收到SIGUSR1
时要做什么,我还没有定义它。以下是我的代码。但是,程序立即终止,输出为User defined signal 1
。
void usr1_handler();
int main(int argc, char const *argv[])
{
pthread_t tid;
pthread_attr_t attr_obj;
void *thread(void *);
pthread_attr_init(&attr_obj);
pthread_attr_setdetachstate(&attr_obj, PTHREAD_CREATE_DETACHED);
pthread_create(&tid, &attr_obj, thread, (void *)NULL);
while(1)
{
int ret = pthread_kill(tid, SIGUSR1);
sleep(5);
}
return 0;
}
void *thread(void *dummy)
{
int sig;
sigset_t sigmask;
struct sigaction action;
/* set up signal mask to block all in main thread */
sigfillset(&sigmask);
pthread_sigmask(SIG_BLOCK, &sigmask, (sigset_t *)0);
for (;;)
{
int err = sigwait(&sigmask, &sig);
/* define what to do with sig here */
printf("sig is %d\n", sig);
}
pthread_exit((void *)NULL);
}
答案 0 :(得分:0)
目前没有任何东西阻止主函数在创建的线程设置其信号处理之前调用pthread_kill
。确保在主函数调用之前完成对sigfillset
等的调用... int err = sigwait(&sigmask, &sig);
。
由于您已经在使用pthread,因此请使用互斥锁和共享标志变量:
最简单的解决方案是在调用pthread_create之前将信号处理从函数thread
移动到main
。
答案 1 :(得分:0)
你做错了。您明确安排在线程中取消阻止SIGUSR1
,但这恰恰是错误的做法。有些文档没有说清楚(例如sigwait()
的Linux联机帮助页),但是POSIX says:
set
号召唤时,sigwait()
定义的信号已被屏蔽;否则,行为未定义。
(强调补充。)
不要忽视@ AndrewHenle&@ 2501关于竞争条件的评论。你也有。我同意@ 2501,解决这个问题的最简单方法是在主线程中设置信号掩码,以便另一个继承它。启动另一个线程后,不要无法恢复主线程的信号掩码,否则你可能会发现你的程序难以杀死。