Linux中的sigwait(Fedora 13)与OS X相比

时间:2010-06-03 04:15:11

标签: c++ pthreads signals

所以我正在尝试使用pthreads创建一个信号处理程序,它可以在OS X和Linux上运行。下面的代码适用于OS X,但不适用于Fedora 13。

应用程序非常简单。它产生一个pthread,注册SIGHUP并等待一个信号。产生信号处理程序后,我在主线程中阻止SIGHUP,因此信号只应发送到signal_handler线程。

在OS X上运行正常,如果我编译,运行并将SIGHUP发送到它打印“Got SIGHUP”的进程。在Linux上它只会杀死进程(并打印出Hangup)。如果我注释掉signal_handler pthread_create,那么应用程序就不会死。

我知道应用程序会进入sigwait并阻塞,但它不会返回信号代码而只会杀死应用程序。

我使用以下命令运行测试:

g++ test.cc -lpthread -o test
./test &
PID="$!"
sleep 1
kill -1 "$PID"

test.cc

#include <pthread.h>
#include <signal.h>
#include <iostream>

using namespace std;

void *signal_handler(void *arg) {
  int sig;
  sigset_t set;

  sigemptyset(&set);
  sigaddset(&set, SIGHUP);

  while (true) {
    cout << "Wait for signal" << endl;
    sigwait(&set, &sig);
    if (sig == SIGHUP) {
      cout << "Got SIGHUP" << endl;
    }
  }
}

int main() {
  pthread_t handler;
  sigset_t set;

  // Create signal handler
  pthread_create(&handler, NULL, signal_handler, NULL);

  // Ignore SIGHUP in main thread
  sigfillset(&set);
  sigaddset(&set, SIGHUP);
  pthread_sigmask(SIG_BLOCK, &set, NULL);

  for (int i = 1; i < 5; i++) {
    cout << "Sleeping..." << endl;
    sleep(1);
  }

  pthread_join(handler, NULL);
  return 0;
}

1 个答案:

答案 0 :(得分:3)

The POSIX spec for sigwait()说:

  

由set定义的信号应具有   在通话时被阻止   到sigwait();否则,行为   未定义。

你不是这样做的。如果你添加:

pthread_sigmask(SIG_BLOCK, &set, NULL);

signal_handler()之后立即到sigaddset()函数,然后它才能正常工作。