linux
多線程訊號總結(一)
1. 在多線程環境下,產生的訊號是傳遞給整個進程的,一般而言,所有線程都有機會收到這個訊號,進程在收到訊號的的線程上下文執行訊號處理函數,具體是哪個線程執行的難以獲知。
2 signal函數BSD/Linux的實現並不在訊號處理函數調用時,恢複訊號的處理為預設,而是在訊號處理時阻塞此訊號,直到訊號處理函數返回。其他實現可能在調用訊號處理函數時,恢複訊號的處理為預設,因而需要在訊號處理函數中重建訊號處理函數為我們定義的處理函數,在這些系統中,較好的方法是使用sigaction來建立訊號處理函數。
3 發送訊號給進程,哪個線程會收到?APUE說,在多線程的程式中,如果不做特殊的訊號阻塞處理,當發送訊號給進程時,由系統選擇一個線程來處理這個訊號。
4 如果進程中,有的線程可以屏蔽了某個訊號,而某些線程可以處理這個訊號,則當我們發送這個訊號給進程或者進程中不能處理這個訊號的線程時,系統會將這個訊號投遞到進程號最小的那個可以處理這個訊號的線程中去處理。
5 如果我們同時註冊了訊號處理函數,同時又用sigwait來等待這個訊號,誰會取到訊號?經過實驗,Linux上sigwait的優先順序高。
6 在Linux中的posix執行緒模式中,線程擁有獨立的進程號,可以通過getpid()得到線程的進程號,而線程號儲存在pthread_t的值中。而主線程的進程號就是整個進程的進程號,因此向主進程發送訊號只會將訊號發送到主線程中去。如果主線程設定了訊號屏蔽,則訊號會投遞到一個可以處理的線程中去。
7 當調用SYSTEM函數去執行SHELL命令時,可以放心的阻塞SIGCHLD,因為SYSTEM會自己處理子進程終止的問題。
8 使用sleep()時,要以放心的去阻塞SIGALRM訊號,目前sleep函數都不會依賴於ALRM函數的SIGALRM訊號來工作。
linux
多線程訊號總結(二)
1. 預設情況下,訊號將由主進程接收處理,就算訊號處理函數是由子線程註冊的2. 每個線程均有自己的訊號屏蔽字,可以使用sigprocmask函數來屏蔽某個線程對該訊號的響應處理,僅留下需要處理該訊號的線程來處理指定的訊號。
3. 對某個訊號處理函數,以程式執行時最後一次註冊的處理函數為準,即在所有的線程裡,同一個訊號在任何線程裡對該訊號的處理一定相同4. 可以使用pthread_kill對指定的線程發送訊號APUE的說法:每個線程都有自己的訊號屏蔽字,但是訊號的處理是進程中所有的線程共用的,這意味著儘管單個線程可以阻止某些訊號,但當線程修改了與某個訊號相關的處理行為後,所有的線程都共用這個處理行為的改變。這樣如果一個線程選擇忽略某個訊號,而其他線程可以恢複訊號的預設處理行為,或者為訊號設定一個新的處理常式,從而可以撤銷上述線程的訊號選擇。
進程中的訊號是送到單個線程的,如果訊號與硬體故障或者計時器逾時有關,該型號就被發送到引起該事件的線程中去,而其他的訊號則被發送到任意一個線程。
sigprocmask的行為在多線程的進程中沒有定義,線程必須使用pthread_sigmask總結:一個訊號可以被沒屏蔽它的任何一個線程處理,但是在一個進程內只有一個多個線程共用的處理函數。……
linux 多線程訊號總結(三)
1 Linux 多線程應用中,每個線程可以通過調用pthread_sigmask() 設定本線程的訊號掩碼。一般情況下,被阻塞的訊號將不能中斷此線程的執行,除非此訊號的產生是因為程式運行出錯如SIGSEGV;另外不能被忽略處理的訊號SIGKILL 和SIGSTOP 也無法被阻塞。
2 當一個線程調用pthread_create() 建立新的線程時,此線程的訊號掩碼會被新建立的線程繼承。
3 訊號安裝最好採用sigaction方式,sigaction,是為替代signal 來設計的較穩定的訊號處理,signal的使用比較簡單。signal(signalNO,signalproc);不能完成的任務是:1.不知道訊號產生的原因;2.處理訊號中不能阻塞其他的訊號而signaction,則可以設定比較多的訊息。尤其是在訊號處理函數過程中接受訊號,進行何種處理。
sigaction函數用於改變進程接收到特定訊號後的行為。
4 sigprocmask函數只能用於單線程,在多線程中使用pthread_sigmask函數。
5 訊號是發給進程的特殊訊息,其典型特性是具有非同步性。
6 訊號集代表多個訊號的集合,其類型是sigset_t. 7 每個進程都有一個訊號掩碼(或稱為訊號屏蔽字),其中定義了當前進程要求阻塞的訊號集。
8 所謂阻塞,指Linux核心不向進程交付在掩碼中的所有訊號。於是進程可以通過修改訊號掩碼來暫時阻塞特定訊號的交付,被阻塞的訊號不會影響進程的行為直到該訊號被真正交付。
9 忽略訊號不同於阻塞訊號,忽略訊號是指Linux核心已經嚮應用程式交付了產生的訊號,只是應用程式直接丟棄了該訊號而已。
http://blog.csdn.net/sctq8888/article/details/7427227