訊號「未決」與「阻塞」

2022-10-11 02:00:13 字數 2184 閱讀 7511

訊號狀態:

訊號的」未決「是一種狀態,指的是從訊號的產生到訊號被處理前的這一段時間;訊號的」阻塞「是乙個開關動作,指的是阻止訊號被處理,但不是阻止訊號產生。 

apue例題在sleep前用sigprocmask阻塞了退出訊號,然後sleep,然後在sleep的過程中產生乙個退出訊號,但是此時退出訊號被阻塞過,(中文的」阻塞」在這裡容易被誤解為一種狀態,實際上是一種類似於開關的動作,所以說「被阻塞過」,而不是「被阻塞」)所以處於「未決」狀態,在 sleep後又用sigprocmask關掉退出訊號的阻塞開關,因為之前產生的退出訊號一直處於未決狀態,當關上阻塞開關後,馬上退出「未決」狀態,得到處理,這一切發生在sigprocmask返回之前。 

訊號生命週期:

對於乙個完整的訊號生命週期(從訊號傳送到相應的處理函式執行完畢)來說,可以分為三個重要的階段,這三個階段由四個重要事件來刻畫:1.訊號誕生;2. 訊號在程序中註冊完畢;3.訊號在程序中的登出完畢;4.訊號處理函式執行完畢。相鄰兩個事件的時間間隔構成訊號生命週期的乙個階段。

下面闡述四個事件的實際意義:

1.訊號"誕生"。訊號的誕生指的是觸發訊號的事件發生(如檢測到硬體異常、定時器超時以及呼叫訊號傳送函式kill()或sigqueue()等)。 

2.訊號在目標程序中"註冊";

程序的task_struct結構中有關於本程序中未決訊號的資料成員: 

struct sigpending pending;

struct sigpending;第

一、第二個成員分別指向乙個sigqueue型別的結構鏈(稱之為"未決訊號資訊鏈")的首尾,第三個成員是程序中所有未決訊號集,資訊鏈中的每個sigqueue結構體刻畫乙個特定訊號所攜帶的資訊,並指向下乙個sigqueue結構: 

struct sigqueue

;訊號在程序中註冊指的就是訊號值加入到程序的未決訊號集中(sigpending結構的第二個成員sigset_t signal),並且訊號所攜帶的資訊被保留到未決訊號資訊鏈的某個sigqueue結構中。只要訊號在程序的未決訊號集中,表明程序已經知道這些訊號的存在,但還沒來得及處理,或者該訊號被程序阻塞。 

注: 當乙個實時訊號傳送給乙個程序時,不管該訊號是否已經在程序中註冊,都會被再註冊一次,因此,訊號不會丟失,因此,實時訊號又叫做"可靠訊號"。這意味著同乙個實時訊號可以在同乙個程序的未決訊號資訊鏈中占有多個sigqueue結構(程序每收到乙個實時訊號,都會為它分配乙個結構來登記該訊號資訊,並把該結構新增在未決訊號鏈尾,即所有誕生的實時訊號都會在目標程序中註冊); 

當乙個非實時訊號傳送給乙個程序時,如果該訊號已經在程序中註冊,則該訊號將被丟棄,造成訊號丟失。因此,非實時訊號又叫做"不可靠訊號"。這意味著同乙個非實時訊號在程序的未決訊號資訊鏈中,至多占有乙個sigqueue結構(乙個非實時訊號誕生後,(1)、如果發現相同的訊號已經在目標結構中註冊,則不再註冊,對於程序來說,相當於不知道本次訊號發生,訊號丟失;(2)、如果程序的未決訊號中沒有相同訊號,則在程序中註冊自己)。 

3.訊號在程序中的登出。在目標程序執行過程中,會檢測是否有訊號等待處理(每次從系統空間返回到使用者空間時都做這樣的檢查)。如果存在未決訊號等待處理且該訊號沒有被程序阻塞,則在執行相應的訊號處理函式前,程序會把訊號在未決訊號鏈中占有的結構卸掉。是否將訊號從程序未決訊號集中刪除對於實時與非實時訊號是不同的。對於非實時訊號來說,由於在未決訊號資訊鏈中最多隻占用乙個sigqueue結構,因此該結構被釋放後,應該把訊號在程序未決訊號集中刪除(訊號登出完畢);而對於實時訊號來說,可能在未決訊號資訊鏈中占用多個sigqueue結構,因此應該針對占用gqueue結構的數目區別對待:如果只占用乙個sigqueue結構(程序只收到該訊號一次),則應該把訊號在程序的未決訊號集中刪除(訊號登出完畢)。否則,不在程序的未決訊號集中刪除該訊號(訊號登出完畢)。程序在執行訊號相應處理函式之前,首先要把訊號在程序中登出。 

4.訊號生命終止。程序登出訊號後,立即執行相應的訊號處理函式,執行完畢後,訊號的本次傳送對程序的影響徹底結束。 

注: 1)訊號註冊與否,與傳送訊號的函式(如kill()或sigqueue()等)以及訊號安裝函式(signal()及sigaction())無關,只與訊號值有關(訊號值小於sigrtmin的訊號最多隻註冊一次,訊號值在sigrtmin及sigrtmax之間的訊號,只要被程序接收到就被註冊)。 

2)在訊號被登出到相應的訊號處理函式執行完畢這段時間內,如果程序又收到同一訊號多次,則對實時訊號來說,每一次都會在程序中註冊;而對於非實時訊號來說,無論收到多少次訊號,都會視為只收到乙個訊號,只在程序中註冊一次。

訊號「未決」與「阻塞」

訊號狀態 訊號的 未決 是一種狀態,指的是從訊號的產生到訊號被處理前的這一段時間 訊號的 阻塞 是乙個開關動作,指的是阻止訊號被處理,但不是阻止訊號產生。apue例題在sleep前用sigprocmask阻塞了退出訊號,然後sleep,然後在sleep的過程中產生乙個退出訊號,但是此時退出訊號被阻塞...

linux訊號阻塞與未決

執行訊號的處理動作稱為訊號遞達 delivery 訊號從產生到遞達之間的狀態,稱為訊號未決 pending 程序可以選擇阻塞 block 某個訊號。被阻塞的訊號產生時將保持在未決狀態,直到程序解除對此訊號的阻塞,才執行遞達的動作。注意,阻塞和忽略是不同,只要訊號被阻塞就不會遞達,而忽略是在遞達之後可...

linux基礎 訊號阻塞及未決訊號

未決訊號 pause的使用 訊號傳送處理過程 可重入函式 訊號處理函式的繼承 setitimer實現定時器 程序可以設定對某個訊號的阻塞 遮蔽 需要用到sigset t 訊號集 資料型別。sigemptyset 3 include int sigemptyset sigset t set 功能 將訊...