2011-06-03 84 views
12

Linux的编程接口书提到的方法用于与异步信号在一个多线程程序进行处理:处理异步信号在多线程程序

  • 的所有线程屏蔽所有的异步信号的该过程 可能会收到。执行 的最简单方法是在创建任何其他线程 之前,阻止 主线程中的信号。随后创建的每个线程都将继承线程的主要信号掩码副本 。
  • 创建一个单一的专用线程,接受使用的输入信号 sigwaitinfo(),sigtimedwait()sigwait()

该方法的优点是 异步生成的信号是 同步接收。由于它接受 传入信号,专用线程 可以安全地修改共享变量 (在互斥控制下)并呼叫 非异步安全功能。它也可以是 信号状态变量,以及其他线程和进程通信 和同步机制 。

现在的问题:

    当内核想传递它选择内部处理任意线程的一个信号
  1. 。从哪里可以知道将信号传递给专用线程?
  2. pthread API是非异步安全功能。那么我们如何在信号处理程序中使用它们呢?

回答

8

当内核提供了一个过程向信号,它选择线程不具有的信号的一种封端。这意味着它从不会选择除信号处理线程之外的任何线程(就像它在sigwaitinfo()或类似程序中阻止信号时一样)。换句话说,内核知​​道在哪里传递信号,因为你已经安排了一些东西,使信号处理线程成为唯一允许传递信号的线程。

你这样做不是使用pthreads API或信号处理程序中的任何非异步信号安全函数。概述的解决方案不处理信号处理程序内的信号 - 它在sigwaitinfo()返回后处理信号处理线程正常执行流程内的信号。这使得它可以访问非异步信号安全功能,这是完整的一点。

3

请记住,建议是在生成任何线程或接收任何信号之前,在进程执行的早期阻止信号(使用pthread_sigmask())。

回答您的问题:

  1. 阅读手册页sigwait()(和/或sigwaitinfo())。当内核想要发送你的进程信号,但所有的线程都阻塞了信号时,信号就会“排队”。它一直排队,直到(a)某个线程解除信号阻塞;或者(b)某些线程在信号上调用sigwait()或sigwaitinfo()。这里的建议是专门用线程来完成后者。

  2. 这个想法是你永远不会运行任何信号处理程序,因为没有线程曾经解锁信号。相反,一个线程用sigwait()等待信号,然后处理信号。这一切都发生在之外的信号处理上下文,这是提案的美妙之处。

+0

Sigaction不用于阻塞信号,请参阅sigprocmask和pthread_sigmask。 – 2017-01-30 02:27:42

+0

@ToddFreed:相信与否,那实际上就是我的意思......修正;谢谢 – Nemo 2017-01-30 19:05:46

0

您可以使用其他机制间接调用来自信号处理程序的pthread API。 在主线程中,创建一个侦听某些命令的Unix域套接字。信号处理程序可以有代码连接到套接字并将命令发送到主线程以调用您希望被调用的pthread API。