对于 MacOS pthreads,sigwait() 不处理信号
For MacOS pthreads, sigwait() Does Not Handle a Signal
当 运行 执行以下操作时,sigwait() 从不处理 SIGUSR1
信号。基本设置是:main 产生两个 pthread:一个处理程序线程和一个工作线程。主线程和两个派生线程阻塞 SIGUSR1。 worker 两次触发 SIGUSR1,延迟两秒。处理程序线程永远不会看到它。
这是在 MacOS 上。当从 Xcode 执行 运行ning 时,我插入一个执行 pro hand -p true -s false SIGUSR1
的可连续断点。如果我从命令行 运行 可执行文件,则会出现相同的输出。
为什么 sigwait()
看不到凸起的 SIGUSR1?
这是输出:
SigHandlerThread: Waiting: 30
Raise
Raise
Program ended with exit code: 0
代码如下:
//
// Signal Test
//
typedef void* (*ThreadRoutine) (void*); // pthread_create
void workerRaise (int signum) {
sleep (2);
printf ("Raise\n");
raise (signum);
}
void sigBlock (sigset_t *set, int signum) {
sigemptyset(set);
sigaddset(set, signum);
pthread_sigmask(SIG_BLOCK, set, NULL);
}
void *sigHandlerThread (void *ignore) {
int signal;
sigset_t blockSignalSet;
sigBlock(&blockSignalSet, SIGUSR1);
printf ("SigHandlerThread: Waiting: %d\n", SIGUSR1);
while (0 == sigwait(&blockSignalSet, &signal))
printf ("SigHandlerThread: %d\n", signal);
printf ("SigHandlerThread: Exit (0 != sigwait())\n");
return NULL;
}
void *workerThread (void *ignore) {
sigset_t blockSignalSet;
sigBlock(&blockSignalSet, SIGUSR1);
workerRaise(SIGUSR1);
workerRaise(SIGUSR1);
pthread_exit(NULL);
}
// Called from main.
void testSignal () {
sigset_t blockSignalSet;
sigBlock(&blockSignalSet, SIGUSR1);
pthread_t worker, handler;
pthread_create (&handler, NULL, (ThreadRoutine) sigHandlerThread, NULL);
pthread_create (&worker, NULL, (ThreadRoutine) workerThread, NULL);
pthread_join(worker, NULL);
sleep (2);
}
raise()
函数发送专门针对调用线程的信号 - 进程中的其他线程不会接收到它。 raise(signum)
等同于 pthread_kill(pthread_self(), signum)
.
您需要的是进程导向信号,而不是线程导向信号。不要使用 raise(signum)
,而是使用 kill(getpid(), signum)
.
当 运行 执行以下操作时,sigwait() 从不处理 SIGUSR1
信号。基本设置是:main 产生两个 pthread:一个处理程序线程和一个工作线程。主线程和两个派生线程阻塞 SIGUSR1。 worker 两次触发 SIGUSR1,延迟两秒。处理程序线程永远不会看到它。
这是在 MacOS 上。当从 Xcode 执行 运行ning 时,我插入一个执行 pro hand -p true -s false SIGUSR1
的可连续断点。如果我从命令行 运行 可执行文件,则会出现相同的输出。
为什么 sigwait()
看不到凸起的 SIGUSR1?
这是输出:
SigHandlerThread: Waiting: 30
Raise
Raise
Program ended with exit code: 0
代码如下:
//
// Signal Test
//
typedef void* (*ThreadRoutine) (void*); // pthread_create
void workerRaise (int signum) {
sleep (2);
printf ("Raise\n");
raise (signum);
}
void sigBlock (sigset_t *set, int signum) {
sigemptyset(set);
sigaddset(set, signum);
pthread_sigmask(SIG_BLOCK, set, NULL);
}
void *sigHandlerThread (void *ignore) {
int signal;
sigset_t blockSignalSet;
sigBlock(&blockSignalSet, SIGUSR1);
printf ("SigHandlerThread: Waiting: %d\n", SIGUSR1);
while (0 == sigwait(&blockSignalSet, &signal))
printf ("SigHandlerThread: %d\n", signal);
printf ("SigHandlerThread: Exit (0 != sigwait())\n");
return NULL;
}
void *workerThread (void *ignore) {
sigset_t blockSignalSet;
sigBlock(&blockSignalSet, SIGUSR1);
workerRaise(SIGUSR1);
workerRaise(SIGUSR1);
pthread_exit(NULL);
}
// Called from main.
void testSignal () {
sigset_t blockSignalSet;
sigBlock(&blockSignalSet, SIGUSR1);
pthread_t worker, handler;
pthread_create (&handler, NULL, (ThreadRoutine) sigHandlerThread, NULL);
pthread_create (&worker, NULL, (ThreadRoutine) workerThread, NULL);
pthread_join(worker, NULL);
sleep (2);
}
raise()
函数发送专门针对调用线程的信号 - 进程中的其他线程不会接收到它。 raise(signum)
等同于 pthread_kill(pthread_self(), signum)
.
您需要的是进程导向信号,而不是线程导向信号。不要使用 raise(signum)
,而是使用 kill(getpid(), signum)
.