为单个线程创建信号处理程序

时间:2013-11-19 01:51:36

标签: c unix signals posix signal-handling

我想知道sigaction是否会为调用线程或整个进程创建信号处理程序。如果它取消阻塞信号并为整个过程创建信号处理程序,那么我怎样才能确保只有一个线程将使用信号处理程序并让其他线程阻止信号。

在我的情况下,我希望一个线程在报警信号关闭时调用信号处理程序而其他线程只是阻止它。


void alarmSigHandler(int signo){

}

void* alarm_thread_start_routine(void *arg){

    // Perform some tasks

}


int main(){

    // Main thread start

    /* Unblock alarm signal */
    /* Assign signal handler for alarm signal */

    /* Launch alarm signal handler thread */

    /* Block alarm signal with pthread_sigmask */

    /* Do something */

    return 0;
}

http://vip.cs.utsa.edu/classes/cs3733f2013/notes/SignalsAndThreads.html

如果信号发送到线程程序,任何线程都可以处理信号。

每个线程都继承了进程信号掩码,但每个线程都有自己的信号掩码,可以使用pthread_sigmask进行修改。

sigprocmask不应该在线程环境中使用,但可以在创建线程之前使用它。

在多线程环境中处理信号的最简单方法是使用专用于信号处理的线程。

涉及信号安全的问题可以通过使用sigwait来处理:

The main process blocks all signals before creating any threads.
No signal handlers are set up.
A thread is created to handle the signals.
That thread sets up a sigset_t containing the signals of interest.
It loops, calling sigwait and handles the pending signals.

2 个答案:

答案 0 :(得分:2)

你说:

  

在我的情况下,我想要一个线程在报警信号关闭时调用信号处理程序而其他线程只是阻止它。

试试这个:

void *alrm_thread(void *arg) {
  // install SIGALRM handler
  // unblock SIGALRM
  ... do stuff ...
}

int main(int argc, char **argv) {
  // block SIGALRM
  // spawn alarm_thread
  ... do stuff or spawn other threads ..
}

SIGALRM只会传递给上面的“alrm_thread”。

<强>更新

改编Alex Che的恰当评论

这是有效的,因为每个线程都有自己的信号掩码,它继承自创建它的线程。

立即在main()中屏蔽(阻塞)SIGALRM可确保所有后续线程在SIGALRM被阻止时开始生效。我们的特殊线程安装处理程序并取消阻止SIGALRM。由于这个特殊线程是唯一能够接收ALRM的线程,因此它将是运行处理程序的线程。

(现在,有一些信号细微差别就在眼前。处理程序或信号处理是所有线程共享的进程全局属性。信号可以是进程导向的或线程导向的。但是,对于你的情况,这是一个非常常见的情况,以上是合适的。)

答案 1 :(得分:1)

来自man page for signals

  

信号处理是一个每进程属性:在多线程中   应用程序,特定信号的配置是相同的   所有线程。

所以是的,当你设置一个信号处理程序时,它将处理发送给进程的信号;信号不会单独发送到每个线程,而是发送到任何一个未阻止正在发送的特定消息的线程。