unix訊號的問題

2021-08-24 17:13:34 字數 1361 閱讀 3880

早期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...