a給b傳送訊號,b收到訊號之前執行自己的**,收到訊號之後,不管執行到程式的什麼位置,都要暫停執行,去處理訊號,處理完畢再繼續執行。與硬體中斷類似——非同步模式。但訊號是軟體層面上實現的中斷,早期常被稱為"軟中斷"。訊號的特質:由於訊號是通過軟體方法實現,其實現手段導致訊號有很強的延時性。但對於使用者來說,這個延時時間非常短,不易察覺。
每個程序所收到的所有訊號,都是由核心負責傳送的,核心處理
按鍵產生,如:ctrl+c、ctrl+z、ctrl+\系統呼叫產生,如:kill、raise、abort
軟體條件產生,如:定時器 alarm
硬體異常產生,如:非法訪問記憶體(段錯誤)、除0(浮點數例外)、記憶體對齊出錯(匯流排錯誤)
命令產生,如:kill 命令
執行預設動作
忽略(丟棄)
捕捉(該使用者處理函式)
linux核心的程序控制塊 pcb 是乙個結構體,task_struct,除了包含程序id,狀態,工作目錄,使用者id,組id,檔案描述符表,還包含了訊號相關的資訊,主要指阻塞訊號集和未決訊號集。
訊號產生,未決訊號集 中描述該訊號的位立刻翻轉為1,表示該訊號處於未決狀態,當訊號被處理,對應位翻轉回0.這一時刻往往非常短暫。
訊號產生後由於某些原因(主要是阻塞)不能抵達。這類訊號的集合稱之為未決訊號集。在遮蔽解除前,訊號一直處於未決狀態。
與變數三要素類似的,每個訊號也有其必備的4要素,分別是:1. 終端按鍵產生的訊號編號 2. 名稱 3. 事件 4. 預設處理動作
可通過 man 7 signal 檢視幫助文件獲取
2. 硬體異常產生的訊號3. kill函式/命令產生訊號ctrl + c
-->(2)sigint
(終止/中斷) int(中斷)
ctrl + z
-->(20)sigtstp
(暫停/停止) t(終端)
ctrl + \
-->(3)sigquit
(退出)
4. raise 和 abort 函式5. 軟體條件產生訊號int kill(pid_t pid, int sig);
成功:0; 失敗:-1(id非法,訊號非法,普通使用者殺init程序等權級問題),設定 errno
sig
:不推薦直接使用數字,用使用巨集名,因為不同os訊號編號可能不同,但名稱一致
pid > 0
:傳送訊號給指定程序
pid = 0
:傳送訊號給呼叫kill函式程序屬於同一程序組的所有程序
pid < 0
:取 |pid| 傳送給對應程序組
pid = -1
:傳送給程序有許可權傳送的系統中所有程序【程序組】每個程序都屬於乙個程序組,程序組是乙個或多個程序的集合,它們相互關聯,共同完成乙個實體任務,每個程序都有乙個程序組長,預設程序組id與程序組長id相同
alarm 函式設定定時器(鬧鐘)。在指定 seconds 後,核心會給當前程序傳送
(14)sigalrm
訊號。程序收到該訊號,預設動作終止每個程序都有且只有唯一乙個定時器
unsigned int alarm(unsigned int seconds);
返回0或剩餘的秒數,無失敗常用:取消定時器 alarm(0),返回舊鬧鐘餘下秒數
【定時】:與程序狀態無關(自然定時法)!就緒、執行、掛起(阻塞、暫停)、終止、殭屍……無論處於何種狀態,alarm 都計時
【練習】:編寫程式,測試你使用的計算機 1 秒鐘能數多少個數
#include
#include
intmain()
return0;
}
【執行結果】
使用 time 命令檢視程式執行的時間。
real
:程式實際執行的時間
user
:程式在使用者空間執行的時間
sys
:程式在核心中執行的時間實際執行時間 = 系統時間 + 使用者時間 + 等待時間
從執行結果看出,user + sys 相加的時間遠遠小於程式實際執行的時間,那麼該程式大部分時間都在等待,程式主要是在等待硬體,因為需要往控制台上輸出,會消耗時間,如果直接往檔案中寫入(./alarm > out),那麼效率就會很高了
這時候可以看出 user + sys 的時間與實際執行的時間很接近了。所以我們可以得出乙個結論:程式執行的瓶頸在於io,優化程式,首選優化io
setirimer 函式設定定時器(鬧鐘),可代替 alarm 函式。精度微妙 us,可以實現週期定時
int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);
【返回值】成功:0;失敗:-1,設定 errno
【引數】:which
自然定時:itimer_real -> (14)sigarm 計算自然時間
虛擬空間計時(使用者空間):itimer_virtual -> (26)si**talrm 只計算程序占用 cpu 的時間
執行時計時(使用者+核心):itimer_prof -> (27)sigprof 計算占用cpu及執行系統呼叫的時間
【練習】使用setitimer函式實現 alarm 函式,重複計算機 1 秒數數程式
#include
#include
#include
intmain()
return0;
}
【執行結果】
Linux通訊之訊號(二)
訊號捕捉 訊號捕捉特性 核心實現訊號捕捉過程 核心通過讀取未決訊號集來判斷訊號是否應被處理,訊號遮蔽字 mask 可以影響未決訊號集。而我們可以在應用程式中自定義 set 來改變 mask。以達到遮蔽指定訊號的目的。sigset t set typedef unsigned long sigset ...
linux之通訊之訊號學習1
比如我們按下了鍵盤或者其它硬體故障 軟體 最常用傳送訊號的系統函式是kill,raise,alarm 和setitimer 以及sigqueue 函式,軟體 還包括一些非法運算等操作。程序可以通過三種方式來響應乙個訊號 1 忽略訊號,即對訊號不做任何處理,其中,有兩個訊號不能忽略 sigkill 及...
linux程序間通訊之訊號
1 wait 函式 原型 pid t wait int status 子程序退出時,它向父程序傳送乙個sigchld訊號,預設情況是總是忽略sigchld訊號,此時程序狀態一直保留在記憶體中,因此需要父程序去處理改訊號,處理的辦法則是呼叫wait 函式,收集子程序狀態資訊,並清空該資訊 使用wait...