早期unix訊號的問題
1. 訊號可能會丟失:訊號發生了程序卻不知道
2. 訊號控制力弱:
比如有時使用者希望通知核心阻塞訊號(不要忽略該訊號,而是在其發生時記住它,然後在程序作好了準備時再恢復之)這種
阻塞訊號的能力當時並不具備。
3. 訊號被抓獲的時候,訊號處理程式會被重置為dfl。
4. 慢性系統呼叫被中斷時,必須手工重啟之。下面的**便是個例子:
again:
if ( (n = read(fd, buff, buffsize)) < 0)
注意:1. 中斷的是系統呼叫,絕非函式;只有由核心執行的系統呼叫才會被中斷
2. 慢性系統呼叫: 指的是可能使程序永遠阻塞的系統呼叫.
較新的posix.1相容的sigaction並不使它們自動再起動。但可以使用sa_restart選項,使核心再起動由該訊號中斷的系統呼叫。
訊號**捉時執行的動作
程序捕捉到訊號並繼續執行時,它首先執行該訊號處理函式中的指令。如果從訊號處理
函式返回(例如沒有呼叫exit或longjmp),則繼續執行在捕捉到訊號時程序正在執行的正常指令序列(這類似於硬體中斷發生時所做的)。
訊號處理程式中對於errno的處理
考慮乙個訊號處理
函式,它恰好在main剛設定errno之後被呼叫。如果該訊號處理程式呼叫read,則它可能更改errno的值,從而取代了剛由main設定的值。
作為乙個通用規則,當在訊號處理
函式中呼叫上面列出的函式時,應當在其前儲存,在其後恢復errno。(要了解經常**捉到的訊號是sigchld,其訊號處理
函式通常要呼叫一種wait函式,而各種wait函式都能改變errno)
可靠訊號原語
1. 訊號遞送(delivery):
執行訊號處理函式(take action)
2. 訊號未決(pending) :從訊號產生(generation)到訊號遞送之間的時間間隔
3. 訊號阻塞(blocked) :訊號發生時不被遞送,而是暫存並於稍後遞送。(sigkill,sigstop無法被阻塞)
訊號被解除阻塞
1. 當乙個被設定為阻塞的訊號發生多次時,當該訊號被解除
阻塞時,大多數unix系統採用的動作是只遞送該訊號一次(雖然posix.1允許系統遞送該訊號一次或多次。如果遞送該訊號多次,則稱這些訊號排了隊)。
2. 多個被阻塞的不同訊號發生,當訊號被解除
阻塞時,posix.1並沒有規定這些訊號的遞送順序。但是posix.1建議:與程序當前狀態有關的訊號,例如sigsegv在其他訊號之前遞送。
Unix訊號說明
1 sighup 2 sigint 3 sigquit 4 sigill 5 sigtrap 6 sigabrt 7 sigemt 8 sigfpe 9 sigkill 10 sigbus 11 sigsegv 12 sigsys 13 sigpipe 14 sigalrm 15 sigterm 1...
Unix訊號說明
sighup 2 sigint 3 sigquit 4 sigill 5 sigtrap 6 sigabrt 7 sigemt 8 sigfpe 9 sigkill 10 sigbus 11 sigsegv 12 sigsys 13 sigpipe 14 sigalrm 15 sigterm 16 ...
Unix訊號說明
1 sighup 2 sigint 3 sigquit 4 sigill 5 sigtrap 6 sigabrt 7 sigemt 8 sigfpe 9 sigkill 10 sigbus 11 sigsegv 12 sigsys 13 sigpipe 14 sigalrm 15 sigterm 1...