MacOS下pthread_kill随机向错误线程发送信号的问题求助
MacOS下pthread_kill随机向错误线程发送信号的问题求助
大家好,最近我在做跨平台的线程信号处理时遇到了个头疼的问题:Linux上程序跑起来完全正常,但到了MacOS上,用pthread_kill给指定线程发信号时,经常会被错误的线程接收到,直接导致程序崩溃。
具体场景是这样的:我创建了两个线程,它们都在包含SIGUSR1和SIGUSR2的同一个信号集上调用sigwait等待信号。主线程通过pthread_kill分别给第一个线程发SIGUSR1、给第二个线程发SIGUSR2,按道理每个线程应该只收到自己预期的信号,但MacOS上会随机出现线程收到错误信号的情况,触发abort终止程序。
下面是我写的最小可复现代码:
#include <pthread.h> #include <signal.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> int channel[2]; sigset_t set; void *worker(void *input) { int sig; int expected_sig = *(int*)input; for (int i = 0; ; ++i) { // notify the main thread that we are done write(channel[1], &expected_sig, sizeof(int)); // wait for signal from the main thread sigwait(&set, &sig); if (sig != expected_sig) { printf("received incorrect signal at iteration %d\n", i); abort(); } } } int main() { // initialize signal set sigemptyset(&set); sigaddset(&set, SIGUSR1); sigaddset(&set, SIGUSR2); pthread_sigmask(SIG_BLOCK, &set, 0); // initialize the pipe pipe(channel); // create two threads pthread_attr_t attr; pthread_attr_init(&attr); pthread_t id1, id2; int thread1_expected_sig = SIGUSR1; int thread2_expected_sig = SIGUSR2; pthread_create(&id1, &attr, worker, &thread1_expected_sig); pthread_create(&id2, &attr, worker, &thread2_expected_sig); for (int i = 0; i < 10000; ++i) { int data[2]; // wait for the two threads to finish processing. // Note that this is only for avoiding duplicated signal. // It does not matter if `pthread_kill` is executed before or after `sigwait`, // as the signal is blocked. read(channel[0], &data, 2 * sizeof(int)); pthread_kill(id1, thread1_expected_sig); pthread_kill(id2, thread2_expected_sig); } exit(0); }
用clang -pthread <example> -lpthread编译后,程序会在随机几次循环后输出类似「received incorrect signal at iteration X」的错误,然后触发abort终止,这说明pthread_kill发送的信号被错误的线程通过sigwait接收到了。
我本来以为pthread_kill是精准定向到目标线程的,结合sigwait应该只会让目标线程拿到对应信号,但MacOS的表现明显和Linux不一样。有没有大佬知道这是MacOS的实现差异导致的,还是我哪里的用法有问题?有没有什么解决办法能让MacOS上也能保证信号被指定线程接收?
内容来源于stack exchange
相关产品推荐
相关产品推荐

