1. 程式人生 > >linux signal, sigaction.sa_mask, sigwait的區別

linux signal, sigaction.sa_mask, sigwait的區別

signal函式重定向訊號的處理函式,預設為阻塞(BLOCK)模式,就是說在執行一個訊號的處理函式時,再收到同樣的訊號,將直接被阻塞,而不是再次立即呼叫處理函式(不允許中斷巢狀);直到這一次的訊號處理函式呼叫完成之後,未決的被阻賽的中斷會繼續被髮送給程序,從而程序可以再次呼叫訊號處理函式。

sigaction.sa_mask可以設定呼叫訊號處理函式時需要阻塞的訊號;sigaction.sa_flags預設為0,效果跟signal類似,阻塞本身訊號;如果設定為SA_NODEFER,那麼在執行訊號的處理函式時再次收到當前的訊號,也會觸發新處理函式呼叫,這些處理函式的通過遞迴的方式呼叫(允許中斷巢狀)


sigwait從未決佇列裡把阻塞的訊號取出來,原理類似於查詢中斷狀態暫存器;如果判斷有需要的訊號,那麼就可以在後面進行處理。這個函式的好處在於,可以專門其一個執行緒來處理訊號,而不是讓程序隨機響應。在程序啟動時,顯用pthread_sigmask(sigprocmask?)把關心的訊號一一設定為阻賽狀態,然後在子執行緒中用sigwait進行處理。

但是這個函式,並不會改變訊號是否被阻塞的這個配置,也就是說,我們這一次sigwait得到的一個訊號,下次程序再收到這個訊號的時候,它還是被放在未決佇列裡面,阻塞程序響應,而不是直接被程序響應;直到你呼叫sigwait來處理這個訊號之前,這個訊號會一直在阻塞在未決佇列裡面。

以下為轉載:

http://www.cnblogs.com/leeming0222/articles/3994125.html

sig的值有:
1) SIGHUP
本訊號在使用者終端連線(正常或非正常)結束時發出, 通常是在終端的控制程序結束時, 通知同一session內的各個作業, 這時它們與控制終端不再關聯。

登入Linux時,系統會分配給登入使用者一個終端(Session)。在這個終端執行的所有程式,包括前臺程序組和後臺程序組,一般都屬於這個 Session。當用戶退出Linux登入時,前臺程序組和後臺有對終端輸出的程序將會收到SIGHUP訊號。這個訊號的預設操作為終止程序,因此前臺程序組和後臺有終端輸出的程序就會中止。不過可以捕獲這個訊號,比如wget能捕獲SIGHUP訊號,並忽略它,這樣就算退出了Linux登入,wget也能繼續下載。

此外,對於與終端脫離關係的守護程序,這個訊號用於通知它重新讀取配置檔案。

2) SIGINT
程式終止(interrupt)訊號, 在使用者鍵入INTR字元(通常是Ctrl-C)時發出,用於通知前臺程序組終止程序。

3) SIGQUIT
和SIGINT類似, 但由QUIT字元(通常是Ctrl-\)來控制. 程序在因收到SIGQUIT退出時會產生core檔案, 在這個意義上類似於一個程式錯誤訊號。

4) SIGILL
執行了非法指令. 通常是因為可執行檔案本身出現錯誤, 或者試圖執行資料段. 堆疊溢位時也有可能產生這個訊號。

5) SIGTRAP
由斷點指令或其它trap指令產生. 由debugger使用。

6) SIGABRT
呼叫abort函式生成的訊號。

7) SIGBUS
非法地址, 包括記憶體地址對齊(alignment)出錯。比如訪問一個四個字長的整數, 但其地址不是4的倍數。它與SIGSEGV的區別在於後者是由於對合法儲存地址的非法訪問觸發的(如訪問不屬於自己儲存空間或只讀儲存空間)。

8) SIGFPE
在發生致命的算術運算錯誤時發出. 不僅包括浮點運算錯誤, 還包括溢位及除數為0等其它所有的算術的錯誤。

9) SIGKILL
用來立即結束程式的執行. 本訊號不能被阻塞、處理和忽略。如果管理員發現某個程序終止不了,可嘗試傳送這個訊號。

10) SIGUSR1
留給使用者使用

11) SIGSEGV
試圖訪問未分配給自己的記憶體, 或試圖往沒有寫許可權的記憶體地址寫資料.

12) SIGUSR2
留給使用者使用

13) SIGPIPE
管道破裂。這個訊號通常在程序間通訊產生,比如採用FIFO(管道)通訊的兩個程序,讀管道沒開啟或者意外終止就往管道寫,寫程序會收到SIGPIPE訊號。此外用Socket通訊的兩個程序,寫程序在寫Socket的時候,讀程序已經終止。

14) SIGALRM
時鐘定時訊號, 計算的是實際的時間或時鐘時間. alarm函式使用該訊號.

15) SIGTERM
程式結束(terminate)訊號, 與SIGKILL不同的是該訊號可以被阻塞和處理。通常用來要求程式自己正常退出,shell命令kill預設產生這個訊號。如果程序終止不了,我們才會嘗試SIGKILL。

17) SIGCHLD
子程序結束時, 父程序會收到這個訊號。

如果父程序沒有處理這個訊號,也沒有等待(wait)子程序,子程序雖然終止,但是還會在核心程序表中佔有表項,這時的子程序稱為殭屍程序。這種情況我們應該避免(父程序或者忽略SIGCHILD訊號,或者捕捉它,或者wait它派生的子程序,或者父程序先終止,這時子程序的終止自動由init程序來接管)。

18) SIGCONT
讓一個停止(stopped)的程序繼續執行. 本訊號不能被阻塞. 可以用一個handler來讓程式在由stopped狀態變為繼續執行時完成特定的工作. 例如, 重新顯示提示符

19) SIGSTOP
停止(stopped)程序的執行. 注意它和terminate以及interrupt的區別:該程序還未結束, 只是暫停執行. 本訊號不能被阻塞, 處理或忽略.

20) SIGTSTP
停止程序的執行, 但該訊號可以被處理和忽略. 使用者鍵入SUSP字元時(通常是Ctrl-Z)發出這個訊號

21) SIGTTIN
當後臺作業要從使用者終端讀資料時, 該作業中的所有程序會收到SIGTTIN訊號. 預設時這些程序會停止執行.

22) SIGTTOU
類似於SIGTTIN, 但在寫終端(或修改終端模式)時收到.

23) SIGURG
有”緊急”資料或out-of-band資料到達socket時產生.

24) SIGXCPU
超過CPU時間資源限制. 這個限制可以由getrlimit/setrlimit來讀取/改變。

25) SIGXFSZ
當程序企圖擴大檔案以至於超過檔案大小資源限制。

26) SIGVTALRM
虛擬時鐘訊號. 類似於SIGALRM, 但是計算的是該程序佔用的CPU時間.

27) SIGPROF
類似於SIGALRM/SIGVTALRM, 但包括該程序用的CPU時間以及系統呼叫的時間.

28) SIGWINCH
視窗大小改變時發出.

29) SIGIO
檔案描述符準備就緒, 可以開始進行輸入/輸出操作.

30) SIGPWR
Power failure

31) SIGSYS
非法的系統呼叫。

在以上列出的訊號中,程式不可捕獲、阻塞或忽略的訊號有:SIGKILL,SIGSTOP
不能恢復至預設動作的訊號有:SIGILL,SIGTRAP
預設會導致程序流產的訊號有:SIGABRT,SIGBUS,SIGFPE,SIGILL,SIGIOT,SIGQUIT,SIGSEGV,SIGTRAP,SIGXCPU,SIGXFSZ
預設會導致程序退出的訊號有:SIGALRM,SIGHUP,SIGINT,SIGKILL,SIGPIPE,SIGPOLL,SIGPROF,SIGSYS,SIGTERM,SIGUSR1,SIGUSR2,SIGVTALRM
預設會導致程序停止的訊號有:SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU
預設程序忽略的訊號有:SIGCHLD,SIGPWR,SIGURG,SIGWINCH