linux 多線程信號處理總結

linux 多線程信號總結(一)

  1. 在多線程環(huán)境下,產生的信號是傳遞給整個進程的,一般而言,所有線程都有機會收到這個信號,進程在收到信號的的線程上下文執(zhí)行信號處理函數(shù),具體是哪個線程執(zhí)行的難以獲知。也就是說,信號會隨機發(fā)個該進程的一個線程。

  2. signal函數(shù)BSD/Linux的實現(xiàn)并不在信號處理函數(shù)調用時,恢復信號的處理為默認,而是在信號處理時阻塞此信號,直到信號處理函數(shù)返回。其他實現(xiàn)可能在調用信號處理函數(shù)時,恢復信號的處理為默認方式,因而需要在信號處理函數(shù)中重建信號處理函數(shù)為我們定義的處理函數(shù),在這些系統(tǒng)中,較好的方法是使用sigaction來建立信號處理函數(shù)。

  3. 發(fā)送信號給進程,哪個線程會收到?APUE說,在多線程的程序中,如果不做特殊的信號阻塞處理,當發(fā)送信號給進程時,由系統(tǒng)選擇一個線程來處理這個信號。

  4. 如果進程中,有的線程可以屏蔽了某個信號,而某些線程可以處理這個信號,則當我們發(fā)送這個信號給進程或者進程中不能處理這個信號的線程時,系統(tǒng)會將這個信號投遞到進程號最小的那個可以處理這個信號的線程中去處理。

  5. 如果我們同時注冊了信號處理函數(shù),同時又用sigwait來等待這個信號,誰會取到信號?經過實驗,Linux上sigwait的優(yōu)先級高。

  6. 在Linux中的posix線程模型中,線程擁有獨立的進程號,可以通過getpid()得到線程的進程號,而線程號保存在pthread_t的值中。而主線程的進程號就是整個進程的進程號,因此向主進程發(fā)送信號只會將信號發(fā)送到主線程中去。如果主線程設置了信號屏蔽,則信號會投遞到一個可以處理的線程中去。

  7. 當調用SYSTEM函數(shù)去執(zhí)行SHELL命令時,可以放心的阻塞SIGCHLD,因為SYSTEM會自己處理子進程終止的問題。

  8. 使用sleep()時,要以放心的去阻塞SIGALRM信號,目前sleep函數(shù)都不會依賴于ALRM函數(shù)的SIGALRM信號來工作。

linux 多線程信號總結(二)

  1. 默認情況下,信號將由主進程接收處理,就算信號處理函數(shù)是由子線程注冊的

  2. 每個線程均有自己的信號屏蔽字,可以使用sigprocmask函數(shù)來屏蔽某個線程對該信號的響應處理,僅留下需要處理該信號的線程來處理指定的信號。

  3. 對某個信號處理函數(shù),以程序執(zhí)行時最后一次注冊的處理函數(shù)為準,即在所有的線程里,同一個信號在任何線程里對該信號的處理一定相同

  4. 可以使用pthread_kill對指定的線程發(fā)送信號

APUE的說法:每個線程都有自己的信號屏蔽字,但是信號的處理是進程中所有的線程共享的,這意味著盡管單個線程可以阻止某些信號,但當線程修改了與某個信號相關的處理行為后,所有的線程都共享這個處理行為的改變。這樣如果一個線程選擇忽略某個信號,而其他線程可以恢復信號的默認處理行為,或者為信號設置一個新的處理程序,從而可以撤銷上述線程的信號選擇。

進程中的信號是送到單個線程的,如果信號與硬件故障或者計時器超時有關,該型號就被發(fā)送到引起該事件的線程中去,而其他的信號則被發(fā)送到任意一個線程。

sigprocmask的行為在多線程的進程中沒有定義,線程必須使用pthread_sigmask

總結:一個信號可以被沒屏蔽它的任何一個線程處理,但是在一個進程內只有一個多個線程共用的處理函數(shù)。......

linux 多線程信號總結(三)

  1. Linux 多線程應用中,每個線程可以通過調用pthread_sigmask() 設置本線程的信號掩碼。一般情況下,被阻塞的信號將不能中斷此線程的執(zhí)行,除非此信號的產生是因為程序運行出錯如SIGSEGV;另外不能被忽略處理的信號SIGKILL 和SIGSTOP 也無法被阻塞。

  2. 當一個線程調用pthread_create() 創(chuàng)建新的線程時,此線程的信號掩碼會被新創(chuàng)建的線程繼承。

  3. 信號安裝最好采用sigaction方式,sigaction,是為替代signal 來設計的較穩(wěn)定的信號處理,signal的使用比較簡單。signal(signalNO,signalproc);不能完成的任務是:

    1. 不知道信號產生的原因;
    2. 處理信號中不能阻塞其他的信號

    而signaction,則可以設置比較多的消息。尤其是在信號處理函數(shù)過程中接受信號,進行何種處理。

    sigaction函數(shù)用于改變進程接收到特定信號后的行為。

  4. sigprocmask函數(shù)只能用于單線程,在多線程中使用pthread_sigmask函數(shù)。

  5. 信號是發(fā)給進程的特殊消息,其典型特性是具有異步性。

  6. 信號集代表多個信號的集合,其類型是sigset_t。

  7. 每個進程都有一個信號掩碼(或稱為信號屏蔽字),其中定義了當前進程要求阻塞的信號集。

  8. 所謂阻塞,指Linux內核不向進程交付在掩碼中的所有信號。于是進程可以通過修改信號掩碼來暫時阻塞特定信號的交付,被阻塞的信號不會影響進程的行為直到該信號被真正交付。

  9. 忽略信號不同于阻塞信號,忽略信號是指Linux內核已經向應用程序交付了產生的信號,只是應用程序直接丟棄了該信號而已。

  10. sleep和nanosleep,如果沒有在它調用之前設置信號屏蔽字的話,都可能會被信號處理函數(shù)打斷。參見sleep和nanosleep的mannual。

轉自:http://blog.chinaunix.net/uid-12274566-id-3050955.html

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容