2011-06-03 129 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。