二中斷的概念和分類
三訊號的處理
2 訊號的基本命令和分類
3 訊號的處理方式
4 父子程序對訊號處理方式的比較
5 傳送訊號的主要方式
6 傳送訊號系統函式的解析
(1)vfork()
#include
#include
pid_t vfork(void);
功能:
該函式類似於fork(),都是建立當前正在呼叫程序的子程序,有關細節、返回值以及可能出錯的原因參考fork();
該函式是一種特殊的轉殖,在建立新的程序時不會去複製父程序中的頁表資訊(記憶體空間等);
該函式建立完畢子程序後會掛起父程序,直到子程序終止或者呼叫exec系列函式為止,也就是保證了子程序先執行;
在子程序終止/呼叫exec系列函式之前,子程序共享所有記憶體空間和父程序,包括棧區;
子程序不能從當前函式中返回,也不能呼叫exit(),但是可以呼叫_exit();
(2)exec系列函式
#include
int execl(const char *path, const char *arg, .../* (char *) null */);
功能:
主要用於執行引數指定的檔案指令;
引數:
第乙個引數:字串形式的路徑名;
第二個引數:字串形式的引數,一般指定具體的執行方式;
第三個引數:可變長引數;
返回值:
success —- 無返回值,error —- -1;
如:
使用execl()執行ls -l命令,執行方式如下:
execl("/bin/ls/","ls", "-l", null);
注意:
vfork()本身沒有太大的實際意義,一般與ecec系列的函式搭配使用,主要用於子程序執行與父程序完全不同**段的場合中;
其中vfork()專門用於建立子程序,ecec系列函式專門用於跳轉到全新的**段中;
使用fork()也是可以與exec系列的函式進行搭配使用,但是效率沒有vfork()高,但是最新的fork()內部由採用了寫時拷貝技術來提高fork()的效率;
(3)system()
#include
int system(const
char *command);
功能:
主要用於執行引數指定的shell命令,成功返回命令的退出狀態資訊,失敗返回-1;
(1)基本概念
中斷本質上就是停止當前程式的執行轉而去執行新的程式或者處理意外情況的過程;
(2)基本分類
硬體中斷、軟體中斷;
(1)基本概念
訊號本質上就是一種軟體中斷,它既可以作為兩個程序間通訊的一種機制,更重要的是,訊號總是可以終止乙個程式的執行,它更多地被用於處理意外情況;
(2)基本特性
a. 訊號是非同步的,也就是說程序並不知道訊號何時會到來;
b. 程序既可以傳送訊號,也可以處理訊號;
c. 每個訊號都有乙個名字,用sig開頭;
(1)基本命令
kill -l
:表示檢視當前系統所支援的所有訊號;
要求掌握的訊號:
sigint
訊號2使用ctrl+c來產生該訊號
預設終止程序
sigquit
訊號3使用ctrl+\來產生該訊號
預設終止程序
sigkill
訊號9使用kill -9來產生該訊號
預設終止程序
(2)基本分類
在當前教學系統中所支援的訊號範圍是:1~64,不保證是連續的;
其中1~31之間的訊號叫做不可靠訊號,不支援排隊,訊號可能會丟失,也叫做非實時訊號;(1)處理方式其中34~64之間的訊號叫做可靠訊號,支援排隊,訊號不會丟失,也叫做實時訊號;
預設處理,絕大多數訊號的預設處理方式都是終止程序;
忽略處理;
自定義處理 / 捕獲處理;
(2)相關函式
#include
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
函式原型解析如下:
typedef void (*sighandler_t)(int);
=> typedef void (*)(int) sighandler_t;
sighandler_t signal(int signum, sighandler_t handler);
=> void (*)(int) signal(int signum, void (*)(int) handler);
=> void (*)(int) signal(int signum, void (*handler)(int) );
=> void (*signal(int signum, void (*handler)(int) ) )(int);
=> signal首先是乙個函式;
該函式有兩個形參,乙個是int型別,乙個是函式指標型別;
該函式的返回值型別是乙個函式指標型別
=>上述兩個函式指標都是乙個指向引數為int,返回值型別為void的函式的指標;
函式功能解析如下:
功能:
主要用於設定指定訊號的處理方式;
引數:
第乙個引數:具體的訊號值 / 訊號名稱;
第二個引數:具體的處理方式;
sig_ign - - - - - - - - - 忽略處理(ignore)
sig_dfl - - - - - - - - - 預設處理(default)
自定義函式的位址 - 自定義處理
返回值:
success —- 之前的處理方式,error —- sig_err;
注意:
sigkill這個訊號只能採用預設處理方式進行處理,不能被使用者捕捉,也就是不能用signal()去設定該訊號的處理方式
(1)對於fork()建立的子程序來說,完全照搬父程序對訊號的處理方式,父程序預設,子程序也預設處理;父程序忽略處理,則子程序也忽略處理;父程序自定義處理,子程序也自定義處理;
(2)對於vfork()和execl()啟動的子程序來說,父程序忽略,子程序也忽略;父程序預設,子程序也預設;但是父程序自定義,子程序卻預設處理;
(1)採用鍵盤傳送訊號(只能傳送部分特殊的訊號)
ctrl + c => 可以傳送訊號sigint 2
ctrl + \ => 可以傳送訊號sigquit 3
… …
(2)程式出錯傳送訊號(只能傳送部分特殊的訊號)
段錯誤 => 可以傳送訊號sigsegv 11
(3)使用kill命令傳送訊號(所有訊號都可以傳送)
kill -訊號值 / 訊號名稱 程序號
=> 表示給指定的程序傳送指定的訊號
(4)採用系統函式傳送訊號
kill() / raise() / alarm() / …
(1)kill()
#include
#include
int kill(pid_t pid, int sig);
功能:
主要用於給引數指定的程序傳送引數指定的訊號;
引數:第乙個引數:程序的編號;
>0 - - - - 表示傳送訊號給程序號為pid的程序
0 - - - - - 表示傳送訊號給呼叫程序組中的每乙個程序
-1 - - - – 表示傳送訊號給每乙個程序p,程序1除外;(程序p必須允許呼叫程序傳送訊號給它)
<-1 - - – 表示傳送訊號給id為-pid的程序組中的每乙個程序
第二個引數:訊號值 / 訊號名稱;
0 - - - - 表示不會傳送訊號,只是檢查程序指定的程序是否存在
練習:
vi 11kill.c檔案,首先使用fork()建立子程序,然後子程序開始啟動,並設定對訊號40進行自定義處理,進入無限迴圈;父程序開始啟動,判斷子程序是否存在,若存在則用kill()給子程序傳送訊號40,並觀察程式的執行結果;
明日預報:
(1)訊號的處理
(2)程序間的通訊技術
手機衛士day11
系統程序顯示和隱藏 建立程序管理設定頁面 processmanagersettingactivity 編寫設定頁面布局檔案 監聽checkbox的勾選事件,更新本地sharepreference 根據本地記錄,更新checkbox狀態 boolean showsystem mprefs.getboo...
實習日記 Day11
滴 今日份心得總結卡 今日最大心得其實應該是,穿一條薄褲子還露腳踝的我怕是失了智,早上腿差點都凍僵了 1.不要從別人身上尋求安心 做好自己,降低對人際關係的預期。果然,邊際遞減效應 應驗了,上週還覺得和諧無比的同事 師徒關係,這週就開始覺察到距離感。我曾以為我的認真工作和順利完成任務能得到上司或者師...
區間合併 day 11
區間合併 問題 給定 n 個區間 li,ri 要求合併所有有交集的區間。注意如果在端點處相交,也算有交集。輸出合併完成後的區間個數。例如 1,3 和 2,6 可以合併為乙個區間 1,6 輸入格式 第一行包含整數n。接下來n行,每行包含兩個整數 l 和 r。輸出格式 共一行,包含乙個整數,表示合併區間...