Для pthreads MacOS sigwait () не обрабатывает сигнал - PullRequest
0 голосов
/ 07 февраля 2019

При выполнении следующего sigwait () никогда не обрабатывает сигнал SIGUSR1.Базовая настройка: main порождает два потока: один поток обработчика и один рабочий поток.Основная нить и обе порожденные нити блокируют SIGUSR1.Рабочий поднимает SIGUSR1 дважды с задержкой в ​​две секунды.Поток обработчика никогда его не увидит.

Это на MacOS.При запуске из Xcode я вставляю непрерывную точку останова, которая выполняет 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);
}

1 Ответ

0 голосов
/ 07 февраля 2019

Функция raise() отправляет сигнал, направленный конкретно на вызывающий поток - другие потоки в процессе его не получат.raise(signum) эквивалентно pthread_kill(pthread_self(), signum).

Вам нужен сигнал, ориентированный на процесс, а не поток.Вместо использования raise(signum) используйте kill(getpid(), signum).

...