實際執行訊號的處理動作稱為訊號遞達(delivery)。
訊號從產生到遞達之間的狀態,稱為訊號未決(pending)。
程序可以選擇阻塞(block)某個訊號。被阻塞的訊號產生時將保持在未決狀態,直到程序接觸對此訊號的阻塞,才執行遞達的操作。(阻塞和忽略不同,只有訊號阻塞就不會遞達,而忽略是在訊號遞達之後可選的一種處理動作。而乙個被阻塞的訊號想要遞達,需要先pending再解除阻塞。)
每個訊號都有兩個標誌位分別表示阻塞和未決,還有乙個函式指標表示處理動作。訊號產生時,核心在程序的pcb設定該訊號的未決標誌,直到訊號遞達才清除該標誌。
如果程序在解除對某訊號的阻塞之前這種訊號產生了多次,將如何處理?posix.1允許系統遞達訊號一次或多次。在linux中:常規訊號在遞達之前產生多次只計一次,實時訊號在遞達之前產生多次可以依次放在乙個佇列裡。對於常規訊號,每個訊號只有乙個bit的未決標誌,非0即1,不記錄該訊號產生了多少次,阻塞標誌也是這樣表示的。因此,未決和阻塞標誌可以用相同的資料型別sigset_t來儲存,sigset_t稱為訊號集。
訊號的阻塞就是讓系統暫時保留訊號待以後傳送。由於另外有辦法讓系統忽略訊號,所以一般情況下訊號的阻塞只是暫時的,只是為了防止訊號打斷敏感的操作。
當需要修改某些全域性變數時,可以通過sigprocmask()函式阻塞處理函式中也使用該變數的訊號。
在某些訊號處理函式中,為了防止同類訊號的到來,可以使用sigaction()函式的sa_mask阻塞特定的訊號。
阻塞訊號的作用:使用函式sigprocmask()阻塞訊號的傳遞,只是延遲訊號的到達。訊號會在解除阻塞後繼續傳遞。這種情況往往需要在訊號程式和其它程式共享全域性變數時,如果全域性變數的型別不是sig_atomic_t型別,當一部分程式恰好讀、寫到變數過程中,產生某個訊號,而訊號程式裡會改變該變數,那麼就會產生混亂。為了避免這種混亂,提供程式的可靠性,你必須在操作這類變數前阻塞訊號,操作完成後恢復訊號的傳遞。
訊號集操作函式:
程式:
#include #include void handler(int sig)
void show_pending(sigset_t *pending)
else
}printf("\n");
}int main()
} return 0;
}
執行結果:
程式執行時,每秒鐘把各訊號的未決狀態列印一遍,由於我們阻塞了sigint訊號,則使sigint訊號(ctrl-c)處於未決狀態,按ctrl-z則可以終止程式.
linux訊號 阻塞訊號
1.訊號在核心中的表示 我們知道了訊號產生的各種原因,而實際執行訊號處理的動作,叫做訊號遞達 delivery 訊號從產生到遞達之間的狀態,稱為訊號未決 pending 程序可以選擇阻塞 block 某個訊號。被阻塞的訊號產生時將保持在未決狀態,直到程序解除對此訊號的阻塞,才執行遞達的動作。注意,阻...
Linux下的訊號(二) 阻塞訊號
1,在此之前,必須先了解幾個概念 訊號遞達 delivery 實際執行訊號處理的動作。訊號未決 pending 訊號從產生到遞達之間的狀態。訊號阻塞 block 被阻塞的訊號產生時將保持在未決狀態,直到 程序解除對此訊號的阻塞,才 執行遞達的動作。注意 訊號阻塞和訊號忽略是不同的。只要訊號被阻塞就不...
Linux 阻塞訊號
linux中訊號產生的原因大致有一下三種 鍵盤中斷 命令發出 異常產生中斷 但歸根結底,這些訊號其實都是最終有作業系統發出的。常見的對訊號的處理,無外乎以下三種 忽略終止該程序 自定義行為 對訊號的處理動作叫做訊號遞達,在訊號由產生到遞達的過程中還有一種狀態叫做未決。即訊號雖產生,但是未被處理。這個...