基本概念
1、中斷
當程式接收訊息後中止當前正在執行的程式,轉而執行其它任務,等其它任務執行完成後再返回,這種執行模式叫中斷,分為硬體中斷和軟體中斷。
2、訊號
是一種軟體中斷,由作業系統發出,程式接收後會執行相應的操作。
3、常見訊號
kill -l 顯示所有訊號
sigint ctrl+c 終止
sigquit ctrl+\ 終止+core
sigfpe 除0 終止+core
sigse** 非常記憶體訪問 終止+core
sigkill 終止訊號 終止
4、不可靠訊號和可靠訊號
建立在早期的訊號處理機制上(1~31) 是不可靠訊號。
不支援排除,可能會丟失,同乙個訊號如果連續產生多次,程序可能只接收到一次。
建立在新訊號處理機制上 (34~64) 是可靠訊號,支援排除,不會丟失。
5、訊號**
硬體異常:除0、無效記憶體訪問、未定義指令、匯流排錯誤、軟體異常。
軟體異常:通過一些命令、函式產生的訊號。
6、訊號的處理方式
1、忽略
2、終止程序
3、終止程序並產生core檔案
4、捕獲並處理(當訊號發前,向核心註冊乙個函式,當訊號發生時系統自動執行該函式)。
訊號捕獲:
typedef void (*sighandler_t)(int);
功能:訊號處理函式的格式
sighandler_t signal(int signum, sighandler_t handler);
功能:向訊號註冊乙個訊號處理函式
signum:訊號編號
handler:函式指標
sig_ign 忽略
sig_dfl 按預設處理
返回值:
之前的訊號處理方式
注意:有些系統通過signal註冊的函式只執行一次,如果想持續有效,可以在訊號處理函式中再註冊一次。
注意:子程序會繼承父程序的訊號處理方式,但如果是通過exec系列函式建立的子程序,會恢復預設的訊號處理式。
注意:訊號處理完後會返回到產生訊號的**處理,如果我們捕獲並處理段錯誤或算術異常可能會產生死迴圈,正確處理段錯誤和算術異常應該是備份資料並結束程序。
練習1:測試一下哪些訊號不能**獲處理。
sigkill(9),sigstop(19)
訊號的傳送:
鍵盤:ctrl+c
ctrl+
ctrl+z
錯誤:除0
非法記憶體訪問
硬體故障 匯流排錯誤
命令:kill 訊號 程序號
killall 訊號 程序名
函式:int kill(pid_t pid, int sig);
功能:向指定的程序傳送訊號
int raise(int sig);
功能:向程序自己傳送訊號
void abort(void);
功能:向程序自己傳送sigabrt訊號
unsigned int alarm(unsigned int seconds);
功能:讓核心在seconds後向程序發關這sigalrm訊號
返回值:上次alarm設定的剩餘時間
注意:如果再次呼叫會覆蓋之前的設定,而不會產生兩次鬧鐘訊號。
程序休眠與訊號:
int pause(void);
功能:讓呼叫者進入休眠狀態,直接程序遇到訊號(捕獲處理、程序結束)
返回值:要麼一直休眠不返回,要麼返回-1。
相當於沒有時間限制的sleep
unsigned int sleep(unsigned int seconds);
功能:讓呼叫者進入休眠指定的秒數,當遇到訊號時會提前返回。
返回值:剩餘的休眠時間
訊號集與訊號阻塞:
訊號集:是一種資料型別,可以儲存多個訊號。
sigset_t 128二進位制,每一次都**乙個訊號。
相關函式:
int sigemptyset(sigset_t *set);
功能:清空訊號集
int sigfillset ( sigset_t *set);
功能:填滿訊號集
int sigaddset(sigset_t *set, int signum);
功能:向訊號集中新增訊號
int sigdelset(sigset_t *set, int signum);
功能:從訊號集中刪除訊號
int sigismember(const sigset_t *set, int signum);
功能:測試訊號集中是否有某個訊號
功能:0 不存在
1 存在
-1 訊號非法
訊號阻塞:
當程式在執行一些特殊操作時是不適合處理訊號的,此時可以讓核心先遮蔽訊號,等操作執行完成後再傳送訊號。
當訊號產生時,核心會在其所維護訊號表中為程序設定乙個與該訊號對應的標記,這個過程叫遞送。
從訊號產生到完成遞送有個時間間隔,處於這個間隔的訊號狀態叫未決。
訊號遮蔽就是讓訊號先處於未決狀態,暫停遞送,當遮蔽解除時再繼續遞送。
每個程序都有乙個訊號集用於儲存要遮蔽的訊號。
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
功能:設定要遮蔽的訊號,這些訊號儲存在訊號集裡面。
how:
sig_block 把set中的訊號新增到要遮蔽的訊號集裡。
sig_unblock 從訊號集刪除set的訊號。
sig_setmask 用set替換之前的訊號集。
set:準備好的訊號集
oldset:獲取的訊號的集
int sigpending(sigset_t *set);
功能:獲取未決狀態的訊號
帶附加的訊號處理:
int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
功能:向核心註冊乙個訊號處理方式
signum:要捕獲的訊號
act:訊號處理函式
oldact:獲取舊的訊號處理式
struct sigaction ;
siginfo_t ;
定時器:
int getitimer(int which, struct itimerval *curr_value);
功能:獲取當前的定時方案
which:
itimer_real 真實計時器,程式總的執行時間 sigalrm
itimer_virtual 虛擬計時器 使用者態的執行時間 sigalrm
itimer_prof 實際計時器 使用者態+核心態的執行時間 sigprof
真實計時器 = 實際計時器 + 休眠時間
int setitimer(int which, const struct itimerval *new_value,
struct itimerval *old_value);
功能:設定新的定義方案
struct itimerval ;
struct timeval ;
團體程式設計天梯賽 05
每個pat考生在參加考試時都會被分配兩個座位號,乙個是試機座位,乙個是考試座位。正常情況下,考生在入場時先得到試機座位號碼,入座進入試機狀態後,系統會顯示該考生的考試座位號碼,考試時考生需要換到考試座位就座。但有些考生遲到了,試機已經結束,他們只能拿著領到的試機座位號碼求助於你,從後台查出他們的考試...
05用d程式設計切片
切片,動態陣列的別名.起.尾 是這樣的 即左包右不包 切片不是實體,就像鑰匙一樣.如果切片修改實體,則實體也跟著變了.a.a 大小為0,a.表示陣列長度,等價於陣列.長度.dup複製實體.如下 import std.stdio void main 賦值 int 3 a 1 1,1 int 3 b 2...
力扣程式設計題05
面試題05.替換空格 請實現乙個函式,把字串 s 中的每個空格替換成 20 示例 1 限制 0 s 的長度 10000 class solution 1221.分割平衡字串 在乙個 平衡字串 中,l 和 r 字元的數量是相同的。給出乙個平衡字串 s,請你將它分割成盡可能多的平衡字串。返回可以通過分割...