对于 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).