sigwait()在多线程程序中无响应问题技术求助
解决sigwait线程无法捕获信号的问题
看起来你的代码里有两个关键问题导致sigwait线程收不到SIGUSR1信号,咱们一步步拆解:
问题1:线程函数签名不符合pthread要求
你的信号线程函数signal_thread带了C++默认参数void *arg = nullptr,但pthread库是基于C接口的,它要求线程启动函数的签名必须是严格的void *(*)(void *)——也就是必须接受一个void*参数,不能有默认值。这个问题会导致pthread_create调用失败,信号线程根本没启动起来,自然无法处理信号。
问题2:信号掩码设置顺序错误
你是先创建信号线程,再在主线程中设置信号掩码。这会导致信号线程启动时继承的是主线程原始的信号掩码(默认不阻塞任何信号),之后你在信号线程里调用pthread_sigmask(SIG_BLOCK, &sigset, NULL)虽然会阻塞所有信号,但更合理的做法是先在主线程阻塞所有信号,再创建线程,这样线程直接继承已阻塞的掩码,避免中间出现信号漏处理的可能。
修正后的代码
#include <stdio.h> #include <pthread.h> #include <signal.h> #include <unistd.h> static void * signal_thread(void *arg) { // 去掉默认参数,严格匹配pthread要求 int sig = -1; sigset_t sigset; sigfillset(&sigset); // 这里可以不用重复调用pthread_sigmask,因为线程已继承主线程的阻塞掩码 // 若要强化保障,也可保留该调用 // pthread_sigmask(SIG_BLOCK, &sigset, NULL); while(1) { int s = sigwait(&sigset, &sig); if(s == 0) printf("SIG %d received!...\n", sig); usleep(20); } } int main() { sigset_t signalset; pthread_t thread; // 第一步:先在主线程阻塞所有信号,让后续创建的线程直接继承该掩码 sigfillset(&signalset); pthread_sigmask(SIG_BLOCK, &signalset, NULL); // 第二步:创建信号处理线程,同时检查创建是否成功 int ret = pthread_create(&thread, NULL, &signal_thread, nullptr); if(ret != 0) { printf("Failed to create thread: %d\n", ret); return 1; } while(1) { raise(SIGUSR1); usleep(200000); // 延长睡眠时间,避免输出过于频繁 } return 0; }
额外说明
sigwait的工作逻辑是:等待当前线程已阻塞的信号,当信号到达时,它会从进程的挂起信号队列中取出该信号并返回,不会触发传统的信号处理函数。所以必须确保目标信号被线程阻塞,这也是我们先在主线程设置掩码的核心原因。- 编译时记得链接pthread库,例如使用命令:
g++ your_code.cpp -o your_program -pthread
内容的提问来源于stack exchange,提问作者Resist
相关产品推荐
相关产品推荐

