




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、-今天內(nèi)容: (1)中斷的概念 (2)信號的概念和函數(shù) 2 3 7 9 111.中斷(1)概念 表示暫時停止當前程序的執(zhí)行,轉(zhuǎn)而執(zhí)行新的程序或者處理意外情況的過程(2)分類 中斷分為:硬件中斷 和 軟件中斷 ctrl+c 段錯誤2.信號的概念和函數(shù)2.1 信號的初識(1)概念 信號就是軟中斷,信號既可以作為進程間的一種通信方式,也可以中斷一個正在執(zhí)行的程序,所以更多地用于處理意外情況(2)特點 a. 信號是異步的 b. 進程既可以處理信號,也可以發(fā)送信號給指定的進程 c. 每個信號都有一個名字,這些名字以SIG開頭如: ctrl+c 是:SIGINT 值為:22.2 信號的命令和分類(1)命令
2、 kill -l => 表示查看當前操作系統(tǒng)中的所有信號(小括號里面是信號的值)掌握的信號: ctrl+c 信號2 SIGINT 默認處理是 終止進程 ctrl+ 信號3 SIGQUIT 默認處理是 終止進程 kill -9 信號9 SIGKILL 不允許被捕捉,終止進程 總線錯誤 信號7 SIGBUS 段錯誤 信號11 SIGSEGV其他信號: (2)分類 一般來說,linux系統(tǒng)中信號164,不保證連續(xù),unix系統(tǒng)的信號和linux系統(tǒng)可能有所不同,unix系統(tǒng)中的信號一般是148 以linux系統(tǒng)為例,做以下分類: 131 叫做不可靠信號,信號可能丟失,不支持排隊(可能會出現(xiàn)插隊
3、的情況),又叫做非實時信號 3464叫做可靠信號,信號不會丟失,支持排隊,又叫做實時信號2.3 信號的處理方式(1)默認處理,絕大多數(shù)都是終止進程(2)忽略信號(3)自定義處理信號,通過自定義函數(shù)進行處理注意: a.信號9只能進行默認處理,不能忽略,也不能進行自定義處理 b.信號的發(fā)送受到用戶的限制,一般來說,每個用戶只能給自己的進程發(fā)信號,root用戶可以給所有進程發(fā)信號2.4 信號的處理函數(shù) #include <signal.h> typedef void (*sighandler_t)(int);/給函數(shù)指針其別名,給*sighandler起別名 sighandler_t s
4、ignal(int signum, sighandler_t handler);解析: typedef void (*)(int) sighandler_t; 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是個函數(shù) =>函數(shù)的第一個參數(shù)是int類型的(信號值),第
5、二個參數(shù)是函數(shù)指針類型的(處理方式) =>函數(shù)的返回值是函數(shù)指針類型的 =>函數(shù)指針是一個指向參數(shù)為int,返回值為void的函數(shù)函數(shù)的使用: 函數(shù)功能:設(shè)置指定信號的處理方式 第一個參數(shù):表示信號值/信號名稱,int類型的 第二個參數(shù):對信號的處理方式,函數(shù)指針類型的 SIG_IGN - 忽略 SIG_DFL - 默認處理 函數(shù)地址 - 調(diào)用指定的函數(shù)進行自定義處理 返回值:成功返回之前的處理方式,失敗返回SIG_ERR例子:/signal函數(shù)的使用#include <stdio.h>#include <stdlib.h>#include <sign
6、al.h>#include <unistd.h>#include <sys/types.h>void fa(int signo)printf("捕獲到了信號%dn",signo);signal(“3,SIG_DFL”);/信號第一次是自定義處理,信號第二次是默認處理int main(void) /設(shè)置對信號2的處理方式為忽略,注意是終端發(fā)送信號(bash) signal(2,SIG_IGN); /設(shè)置對信號3,進行自定義處理 signal(SIGQUIT,fa); /設(shè)置對信號9,進行自定義處理,不好使 signal(SIGKILL,fa);
7、printf("pid=%dn",getpid); while(1);程序輸出:bash只發(fā)SIGINT SIGQUIT信號,對SIGINT處理是SIG_IGN,SIGQUIT處理是fa(自定義)終端1bash發(fā)送kill -9 10455(進程號),進行自定義處理fa,但是此信號不會被捕捉,默認終止進程終端1終端2終端1 練習: 在主函數(shù)設(shè)置對信號2進行自定義處理,對信號3進行忽略處理,使用fork創(chuàng)建子進程進入無限循環(huán),父進程結(jié)束,然后給子進程發(fā)送信號2和3看效果/練習#include <stdio.h>#include <unistd.h>#i
8、nclude <sys/types.h>#include <signal.h>#include <stdlib.h>void fa(int signo) printf("捕捉到了信號%dn",signo);int main(void) printf("父進程ID=%dn",getpid(); /對信號2進行自定義處理 signal(2,fa); /對信號3進行忽略處理 signal(SIGQUIT,SIG_IGN); /創(chuàng)建子進程,子進程進入死循環(huán) pid_t pid=fork(); if(0=pid) printf(
9、"子進程ID=%dn",getpid(); while(1); printf("父進程結(jié)束,子進程未結(jié)束n"); return 0; /給子進程發(fā)送信號2,信號3ctrl +c發(fā)給的是bash,并不是子進程kill可以指定發(fā)何種信號2.5 父子進程對信號處理方式的比較(1) 對于fork創(chuàng)建的子進程來說,完全照搬父進程對信號的處理方式,父進程忽略,子進程也忽略;父進程默認處理,子進程也默認處理;父進程自定義處理,子進程也自定義處理(2)對于vfork創(chuàng)建的子進程來說,父進程自定義,子進程默認處理;(不同)(子進程中用到execl()函數(shù),自動跳轉(zhuǎn)到別地方
10、,在主函數(shù)中的自定義函數(shù)void fa(int signo)子進程就找不到了,所以就會默認處理父進程中的自定義信號)父進程忽略,子進程忽略;父進程默認處理,子進程也默認處理;2.6 信號的發(fā)送方式(1)鍵盤發(fā)送(只能發(fā)送部分特殊信號,信號9就不能發(fā)送) ctrl+c -> 信號2 SIGINT ctrl+ -> 信號3 SIGQUIT .(2)程序出錯(只能發(fā)送部分特殊信號) 段錯誤 -> 信號11 SIGSEGV 總線錯誤 ->信號7 SIGBUS .(3) kill -信號值 進程號(可以發(fā)送全部信號)(4)采用系統(tǒng)函數(shù)發(fā)送信號 raise()/kill()/ala
11、rm()/sigqueue()2.7 發(fā)送信號的函數(shù)(1)raise函數(shù)(send a signal to the caller) #include <signal.h> int raise(int sig);函數(shù)功能: 表示向正在執(zhí)行的進程/線程發(fā)送參數(shù)指定的信號,成功返回0,失敗返回非0例子:/raise函數(shù)的使用#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>void fa(int signo) printf("捕獲到
12、了信號%dn",signo);int main(void) /先設(shè)置信號的處理方式 signal(2,fa); /10秒自后發(fā)送信號2 sleep(10); raise(SIGINT); while(1); return 0;(b) sleep函數(shù)(sleep for the specified number of seconds) #include <unistd.h> unsigned int sleep(unsigned int seconds);函數(shù)功能: 表示讓進程/線程按照參數(shù)指定的時間進入睡眠,如果睡醒了返回0,如果沒有睡醒被一個不能忽略的信號打斷,則返回剩
13、余的秒數(shù)/raise函數(shù)的使用#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>void fa(int signo) printf("捕獲到了信號%dn",signo);int main(void) /先設(shè)置信號的處理方式 signal(2,fa); /10秒自后發(fā)送信號2 int res=sleep(10); /被一個不可忽略的信號打斷,返回剩余秒數(shù) printf("res=%dn",res); raise
14、(SIGINT); while(1); return 0;(2)kill函數(shù) (send signal to a process) #include <sys/types.h> #include <signal.h> int kill(pid_t pid, int sig);第一個參數(shù):進程號 正數(shù) - 表示給指定單一進程發(fā)信號(單發(fā),掌握) 0 - 表示發(fā)送給與正在運行的進程同組的 每一個進程(了解) -1 - 表示把信號發(fā)送到每一個可以被發(fā)送信號 的進程中,除了進程1(init進程,了解) <-1 - 表示發(fā)送給進程組id為-pid的每一個進程 (了解)第二個
15、參數(shù):信號 0 - 表示檢查指定的進程/進程組的存在性函數(shù)功能:給指定的進程發(fā)送指定的信號/kill函數(shù)的使用#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <sys/types.h>#include <unistd.h>void fa(int signo) printf("捕捉到信號%dn",signo);int main(void) pid_t pid =fork(); if(-1=pid) perror("fork&q
16、uot;),exit(-1); if(0=pid) /自定義處理信號50 signal(50,fa); while(1); sleep(1); /父進程判斷子進程是否存在 if(0=kill(pid,0) printf("父進程%d給子進程%d發(fā)送信號50n",getpid(),pid); kill(pid,50); return 0;(3)alarm函數(shù) (set an alarm clock for delivery of signal) #include <unistd.h> unsigned int alarm(unsigned int seconds)
17、;函數(shù)功能: 表示經(jīng)過參數(shù)指定的秒數(shù)之后發(fā)送SIGALARM信號,函數(shù)返回之前鬧鐘剩余的秒數(shù),之前沒有鬧鐘則返回0 參數(shù)為0時,不會設(shè)置新的鬧鐘,取消之前的鬧鐘/alarm函數(shù)的使用#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>void fa(int signo)printf("捕獲到的信號%dn",signo);int main(void) /設(shè)置SIGALRM信號進行自定義處理 signal(SIGALRM,fa); /
18、5秒之后發(fā)送SIGALRM信號 int res=alarm(5); printf("res=%dn",res);/之前沒有鬧鐘,返回0 sleep(2); res=alarm(10); printf("res=%dn",res);/3 while(1); return 0;例子2:/alarm函數(shù)的使用#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>void fa(int signo) printf(&qu
19、ot;捕獲到的信號%dn",signo); /每隔一秒觸發(fā)一次,類似于遞歸 alarm(1);int main(void) /設(shè)置SIGALRM信號進行自定義處理 signal(SIGALRM,fa); /5秒之后發(fā)送SIGALRM信號 int res=alarm(5); printf("res=%dn",res);/之前沒有鬧鐘,返回0 while(1); return 0;2.8 信號集的概念和使用(1)概念 信號集 - 表示信號的集合 信號集的數(shù)據(jù)類型: sigset_t 128個字節(jié) typedef struct unsigned long int _va
20、l(1024 / (8 * sizeof (unsigned long int); _sigset_t; typedef _sigset_t sigset_t; linux系統(tǒng)表示信號的范圍164,采用最節(jié)省內(nèi)存的方式表示信號,讓每一個二進制位來代表一個信號,則8個字節(jié)足夠,而sigset_t本質(zhì)上就是占用128個字節(jié),然后采用每一個二進制位表示一個信號例子vi 07sigset.c/信號集的概念和基本操作#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h
21、>int main(void) printf("sigset_t=%dn",sizeof(segset_t);/128 return 0;底層的實現(xiàn)方法(2) 基本操作#include <signal.h> sigemptyset() - 清空信號集(二進制置為0) sigfillset() - 填滿信號集(二進制置為1) sigaddset() - 增加一個信號(對應(yīng)二進制置為1) sigdelset() - 刪除一個信號(對應(yīng)二進制置為0) sigismember() - 查找是否存在某個信號 例子:/信號集的概念和基本操作#include <s
22、tdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>int main(void) printf("sigset_t=%dn",sizeof(segset_t);/128 sigset_t set;/先定義信號集 printf("set=%ld",set); /清空信號集 sigemptyset(&set); printf("set=%ld",set); /增加信號到信號集中,第二位二進制置為1 sigaddse
23、t(&set,2); printf("set=%ld",set);/2 sigaddset(&set,3);/2+4=6 printf("set=%ld",set); sigaddset(&set,7);/6+64=70 printf("set=%ld",set); sigdelset(&set,3); printf("set=%ld",set);/70-4=66 if(sigismember(&set,3) printf("信號3存在信號集中n"); i
24、f(sigsimumber(&set,7) printf("信號7存在信號集中n"); return 0;因為是set是sigset_t類型,不是long int類型.這里為了省事這么輸出2.9 信號的屏蔽 在某些特殊情況下不允許程序的執(zhí)行被信號打斷,則需要對信號進行屏蔽來解決此問題(1)sigprocmask函數(shù) (examine and change blocked signals(信號集) #include <signal.h> int sigprocmask(int how, const sigset_t* set, sigset_t *olds
25、et);第一個參數(shù):處理方式 SIG_BLOCK: ABC CDE =>ABCDE(新+舊) SIG_UNBLOCK: ABC CDE=>AB(舊-新) SIG_SETMASK: ABC CDE=>CDE(新的替換舊的,掌握)第二個參數(shù):設(shè)置新的信號屏蔽字(信號集)第三個參數(shù):帶出舊的信號屏蔽字(信號集)函數(shù)功能:主要用于設(shè)置新的信號屏蔽字,帶出之前的信號屏蔽字(2)sigpending 函數(shù)#include <signal>int sigpending(sigset_t *set); 函數(shù)功能:獲取在信號屏蔽期間來過的信號例子:/sigprocmask函數(shù)的使用
26、#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>#include <sys/types.h>void fa(int signo) printf("捕獲到了信號%dn",signo);int main(void) printf("當前進程的進程號%dn",getpid(); /設(shè)置對信號2,信號3,信號50進行自定義處理 signal(2,fa); signal(3,fa); signal(50,fa); int res=sleep(20);/返回未完成的時間 if(0!=res) printf("沒有信號屏蔽,睡眠別喚醒,所以睡了%d秒n",20-res); printf("-n"); printf("開始
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年國網(wǎng)黑龍江省電力有限公司招聘高校畢業(yè)生(第一批)筆試參考題庫附帶答案詳解
- 2025至2030年中國皮手包行業(yè)投資前景及策略咨詢報告
- 工程技術(shù)服務(wù)勞動合同年
- 公司副總經(jīng)理聘用合同書
- 如何有效處理工作中的壓力與焦慮計劃
- 2024年浙江余杭選聘中小學名優(yōu)教師考試真題
- 體化倉儲管理的個人規(guī)劃計劃
- 2024年寧波前灣新區(qū)招聘事業(yè)編制中小學教師考試真題
- 2024年遼寧能源控股集團所屬沈煤集團招聘考試真題
- 2024-2025初中生物實驗室課程評估計劃
- 《一幅不可思議的畫》課件
- 各種玻璃配方知識
- 詳細波士頓診斷性失語癥檢查
- 高溫熔融金屬安全知識(薛生蓮)
- 全國主體功能區(qū)規(guī)劃圖
- ISO22716化工原料檢驗標準
- 充電樁安裝施工流程
- 成績單表格樣表
- 城道路配套燃氣管道工程設(shè)計說明
- 人教三年級數(shù)學下冊:期中復習與檢測教學教案
- ATX電源的工作原理
評論
0/150
提交評論