Linux编程接口手册提到了一种在多线程程序中处理异步信号的方法:
- 所有线程都阻止该进程的所有异步信号 可能会收到。最简单的方法 这是为了阻止信号 任何其他线程之前的主线程 被创造了。每个随后创建 线程将继承main的副本 线程的信号掩码。
- 使用创建一个接受传入信号的专用线程
sigwaitinfo()
,sigtimedwait()
或sigwait()
。这种方法的优点是 异步生成的信号是 同步收到。因为它接受 传入信号,专用线程 可以安全地修改共享变量 (在互斥控制下)和通话 非异步安全功能。它也可以 信号条件变量和emply 其他线程和进程通信 和同步机制。
现在问题:
答案 0 :(得分:8)
当内核提供过程导向信号时,它会选择其中一个没有阻塞信号的线程。这意味着它永远不会选择除信号处理线程之外的任何线程(其行为类似于在sigwaitinfo()
或类似物中阻塞时信号未被阻塞)。换句话说:内核知道在哪里传递信号,因为你已经安排了这样的事情,即信号处理线程是唯一允许传递信号的线程。
你不在信号处理程序中使用pthreads API或任何非异步信号安全函数。概述的解决方案不处理信号处理程序中的信号 - 它在sigwaitinfo()
返回后处理信号处理线程的正常执行流程内的信号。这使得它可以访问非异步信号安全功能,这是重点。
答案 1 :(得分:3)
请记住,提议是在生成任何线程或接收任何信号之前,在进程执行的早期阻止信号(使用pthread_sigmask())。
回答你的问题:
阅读sigwait()(和/或sigwaitinfo())的手册页。当内核想要向您的进程发送信号但是所有线程都阻塞了信号时,信号会“排队”。它保持排队,直到(a)一些线程解锁信号;或(b)某些线程在信号上调用sigwait()或sigwaitinfo()。这里的建议是专门用一个线程来完成后者。
这个想法是你永远不会运行任何信号处理程序,因为没有线程会解锁信号。相反,一个线程用sigwait()等待信号,然后它处理信号。这一切都发生在信号处理环境 之外,这是提案的美妙之处。
答案 2 :(得分:0)
您可以使用其他机制从信号处理程序间接调用pthread API。 在主线程中,创建一个侦听某些命令的Unix域套接字。信号处理程序可以使用代码连接到套接字并将命令发送到主线程以调用您希望调用的pthread API。