Linux入門 訊號(二) 阻塞訊號

2021-08-02 08:09:02 字數 1385 閱讀 7297

實際執行訊號的處理動作稱為訊號遞達(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中訊號產生的原因大致有一下三種 鍵盤中斷 命令發出 異常產生中斷 但歸根結底,這些訊號其實都是最終有作業系統發出的。常見的對訊號的處理,無外乎以下三種 忽略終止該程序 自定義行為 對訊號的處理動作叫做訊號遞達,在訊號由產生到遞達的過程中還有一種狀態叫做未決。即訊號雖產生,但是未被處理。這個...