UC-day09中斷,信號(hào)函數(shù)_第1頁(yè)
UC-day09中斷,信號(hào)函數(shù)_第2頁(yè)
UC-day09中斷,信號(hào)函數(shù)_第3頁(yè)
UC-day09中斷,信號(hào)函數(shù)_第4頁(yè)
UC-day09中斷,信號(hào)函數(shù)_第5頁(yè)
已閱讀5頁(yè),還剩9頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、-今天內(nèi)容: (1)中斷的概念 (2)信號(hào)的概念和函數(shù) 2 3 7 9 111.中斷(1)概念 表示暫時(shí)停止當(dāng)前程序的執(zhí)行,轉(zhuǎn)而執(zhí)行新的程序或者處理意外情況的過(guò)程(2)分類 中斷分為:硬件中斷 和 軟件中斷 ctrl+c 段錯(cuò)誤2.信號(hào)的概念和函數(shù)2.1 信號(hào)的初識(shí)(1)概念 信號(hào)就是軟中斷,信號(hào)既可以作為進(jìn)程間的一種通信方式,也可以中斷一個(gè)正在執(zhí)行的程序,所以更多地用于處理意外情況(2)特點(diǎn) a. 信號(hào)是異步的 b. 進(jìn)程既可以處理信號(hào),也可以發(fā)送信號(hào)給指定的進(jìn)程 c. 每個(gè)信號(hào)都有一個(gè)名字,這些名字以SIG開頭如: ctrl+c 是:SIGINT 值為:22.2 信號(hào)的命令和分類(1)命令

2、 kill -l => 表示查看當(dāng)前操作系統(tǒng)中的所有信號(hào)(小括號(hào)里面是信號(hào)的值)掌握的信號(hào): ctrl+c 信號(hào)2 SIGINT 默認(rèn)處理是 終止進(jìn)程 ctrl+ 信號(hào)3 SIGQUIT 默認(rèn)處理是 終止進(jìn)程 kill -9 信號(hào)9 SIGKILL 不允許被捕捉,終止進(jìn)程 總線錯(cuò)誤 信號(hào)7 SIGBUS 段錯(cuò)誤 信號(hào)11 SIGSEGV其他信號(hào): (2)分類 一般來(lái)說(shuō),linux系統(tǒng)中信號(hào)164,不保證連續(xù),unix系統(tǒng)的信號(hào)和linux系統(tǒng)可能有所不同,unix系統(tǒng)中的信號(hào)一般是148 以linux系統(tǒng)為例,做以下分類: 131 叫做不可靠信號(hào),信號(hào)可能丟失,不支持排隊(duì)(可能會(huì)出現(xiàn)插隊(duì)

3、的情況),又叫做非實(shí)時(shí)信號(hào) 3464叫做可靠信號(hào),信號(hào)不會(huì)丟失,支持排隊(duì),又叫做實(shí)時(shí)信號(hào)2.3 信號(hào)的處理方式(1)默認(rèn)處理,絕大多數(shù)都是終止進(jìn)程(2)忽略信號(hào)(3)自定義處理信號(hào),通過(guò)自定義函數(shù)進(jìn)行處理注意: a.信號(hào)9只能進(jìn)行默認(rèn)處理,不能忽略,也不能進(jìn)行自定義處理 b.信號(hào)的發(fā)送受到用戶的限制,一般來(lái)說(shuō),每個(gè)用戶只能給自己的進(jìn)程發(fā)信號(hào),root用戶可以給所有進(jìn)程發(fā)信號(hào)2.4 信號(hào)的處理函數(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是個(gè)函數(shù) =>函數(shù)的第一個(gè)參數(shù)是int類型的(信號(hào)值),第

5、二個(gè)參數(shù)是函數(shù)指針類型的(處理方式) =>函數(shù)的返回值是函數(shù)指針類型的 =>函數(shù)指針是一個(gè)指向參數(shù)為int,返回值為void的函數(shù)函數(shù)的使用: 函數(shù)功能:設(shè)置指定信號(hào)的處理方式 第一個(gè)參數(shù):表示信號(hào)值/信號(hào)名稱,int類型的 第二個(gè)參數(shù):對(duì)信號(hào)的處理方式,函數(shù)指針類型的 SIG_IGN - 忽略 SIG_DFL - 默認(rèn)處理 函數(shù)地址 - 調(diào)用指定的函數(shù)進(jìn)行自定義處理 返回值:成功返回之前的處理方式,失敗返回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("捕獲到了信號(hào)%dn",signo);signal(“3,SIG_DFL”);/信號(hào)第一次是自定義處理,信號(hào)第二次是默認(rèn)處理int main(void) /設(shè)置對(duì)信號(hào)2的處理方式為忽略,注意是終端發(fā)送信號(hào)(bash) signal(2,SIG_IGN); /設(shè)置對(duì)信號(hào)3,進(jìn)行自定義處理 signal(SIGQUIT,fa); /設(shè)置對(duì)信號(hào)9,進(jìn)行自定義處理,不好使 signal(SIGKILL,fa);

7、printf("pid=%dn",getpid); while(1);程序輸出:bash只發(fā)SIGINT SIGQUIT信號(hào),對(duì)SIGINT處理是SIG_IGN,SIGQUIT處理是fa(自定義)終端1bash發(fā)送kill -9 10455(進(jìn)程號(hào)),進(jìn)行自定義處理fa,但是此信號(hào)不會(huì)被捕捉,默認(rèn)終止進(jìn)程終端1終端2終端1 練習(xí): 在主函數(shù)設(shè)置對(duì)信號(hào)2進(jìn)行自定義處理,對(duì)信號(hào)3進(jìn)行忽略處理,使用fork創(chuàng)建子進(jìn)程進(jìn)入無(wú)限循環(huán),父進(jìn)程結(jié)束,然后給子進(jìn)程發(fā)送信號(hào)2和3看效果/練習(xí)#include <stdio.h>#include <unistd.h>#i

8、nclude <sys/types.h>#include <signal.h>#include <stdlib.h>void fa(int signo) printf("捕捉到了信號(hào)%dn",signo);int main(void) printf("父進(jìn)程ID=%dn",getpid(); /對(duì)信號(hào)2進(jìn)行自定義處理 signal(2,fa); /對(duì)信號(hào)3進(jìn)行忽略處理 signal(SIGQUIT,SIG_IGN); /創(chuàng)建子進(jìn)程,子進(jìn)程進(jìn)入死循環(huán) pid_t pid=fork(); if(0=pid) printf(

9、"子進(jìn)程ID=%dn",getpid(); while(1); printf("父進(jìn)程結(jié)束,子進(jìn)程未結(jié)束n"); return 0; /給子進(jìn)程發(fā)送信號(hào)2,信號(hào)3ctrl +c發(fā)給的是bash,并不是子進(jìn)程kill可以指定發(fā)何種信號(hào)2.5 父子進(jìn)程對(duì)信號(hào)處理方式的比較(1) 對(duì)于fork創(chuàng)建的子進(jìn)程來(lái)說(shuō),完全照搬父進(jìn)程對(duì)信號(hào)的處理方式,父進(jìn)程忽略,子進(jìn)程也忽略;父進(jìn)程默認(rèn)處理,子進(jìn)程也默認(rèn)處理;父進(jìn)程自定義處理,子進(jìn)程也自定義處理(2)對(duì)于vfork創(chuàng)建的子進(jìn)程來(lái)說(shuō),父進(jìn)程自定義,子進(jìn)程默認(rèn)處理;(不同)(子進(jìn)程中用到execl()函數(shù),自動(dòng)跳轉(zhuǎn)到別地方

10、,在主函數(shù)中的自定義函數(shù)void fa(int signo)子進(jìn)程就找不到了,所以就會(huì)默認(rèn)處理父進(jìn)程中的自定義信號(hào))父進(jìn)程忽略,子進(jìn)程忽略;父進(jìn)程默認(rèn)處理,子進(jìn)程也默認(rèn)處理;2.6 信號(hào)的發(fā)送方式(1)鍵盤發(fā)送(只能發(fā)送部分特殊信號(hào),信號(hào)9就不能發(fā)送) ctrl+c -> 信號(hào)2 SIGINT ctrl+ -> 信號(hào)3 SIGQUIT .(2)程序出錯(cuò)(只能發(fā)送部分特殊信號(hào)) 段錯(cuò)誤 -> 信號(hào)11 SIGSEGV 總線錯(cuò)誤 ->信號(hào)7 SIGBUS .(3) kill -信號(hào)值 進(jìn)程號(hào)(可以發(fā)送全部信號(hào))(4)采用系統(tǒng)函數(shù)發(fā)送信號(hào) raise()/kill()/ala

11、rm()/sigqueue()2.7 發(fā)送信號(hào)的函數(shù)(1)raise函數(shù)(send a signal to the caller) #include <signal.h> int raise(int sig);函數(shù)功能: 表示向正在執(zhí)行的進(jìn)程/線程發(fā)送參數(shù)指定的信號(hào),成功返回0,失敗返回非0例子:/raise函數(shù)的使用#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>void fa(int signo) printf("捕獲到

12、了信號(hào)%dn",signo);int main(void) /先設(shè)置信號(hào)的處理方式 signal(2,fa); /10秒自后發(fā)送信號(hào)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ù)功能: 表示讓進(jìn)程/線程按照參數(shù)指定的時(shí)間進(jìn)入睡眠,如果睡醒了返回0,如果沒(méi)有睡醒被一個(gè)不能忽略的信號(hào)打斷,則返回剩

13、余的秒數(shù)/raise函數(shù)的使用#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>void fa(int signo) printf("捕獲到了信號(hào)%dn",signo);int main(void) /先設(shè)置信號(hào)的處理方式 signal(2,fa); /10秒自后發(fā)送信號(hào)2 int res=sleep(10); /被一個(gè)不可忽略的信號(hào)打斷,返回剩余秒數(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);第一個(gè)參數(shù):進(jìn)程號(hào) 正數(shù) - 表示給指定單一進(jìn)程發(fā)信號(hào)(單發(fā),掌握) 0 - 表示發(fā)送給與正在運(yùn)行的進(jìn)程同組的 每一個(gè)進(jìn)程(了解) -1 - 表示把信號(hào)發(fā)送到每一個(gè)可以被發(fā)送信號(hào) 的進(jìn)程中,除了進(jìn)程1(init進(jìn)程,了解) <-1 - 表示發(fā)送給進(jìn)程組id為-pid的每一個(gè)進(jìn)程 (了解)第二個(gè)

15、參數(shù):信號(hào) 0 - 表示檢查指定的進(jìn)程/進(jìn)程組的存在性函數(shù)功能:給指定的進(jìn)程發(fā)送指定的信號(hào)/kill函數(shù)的使用#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <sys/types.h>#include <unistd.h>void fa(int signo) printf("捕捉到信號(hào)%dn",signo);int main(void) pid_t pid =fork(); if(-1=pid) perror("fork&q

16、uot;),exit(-1); if(0=pid) /自定義處理信號(hào)50 signal(50,fa); while(1); sleep(1); /父進(jìn)程判斷子進(jìn)程是否存在 if(0=kill(pid,0) printf("父進(jìn)程%d給子進(jìn)程%d發(fā)送信號(hào)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)過(guò)參數(shù)指定的秒數(shù)之后發(fā)送SIGALARM信號(hào),函數(shù)返回之前鬧鐘剩余的秒數(shù),之前沒(méi)有鬧鐘則返回0 參數(shù)為0時(shí),不會(huì)設(shè)置新的鬧鐘,取消之前的鬧鐘/alarm函數(shù)的使用#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>void fa(int signo)printf("捕獲到的信號(hào)%dn",signo);int main(void) /設(shè)置SIGALRM信號(hào)進(jìn)行自定義處理 signal(SIGALRM,fa); /

18、5秒之后發(fā)送SIGALRM信號(hào) int res=alarm(5); printf("res=%dn",res);/之前沒(méi)有鬧鐘,返回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;捕獲到的信號(hào)%dn",signo); /每隔一秒觸發(fā)一次,類似于遞歸 alarm(1);int main(void) /設(shè)置SIGALRM信號(hào)進(jìn)行自定義處理 signal(SIGALRM,fa); /5秒之后發(fā)送SIGALRM信號(hào) int res=alarm(5); printf("res=%dn",res);/之前沒(méi)有鬧鐘,返回0 while(1); return 0;2.8 信號(hào)集的概念和使用(1)概念 信號(hào)集 - 表示信號(hào)的集合 信號(hào)集的數(shù)據(jù)類型: sigset_t 128個(gè)字節(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)表示信號(hào)的范圍164,采用最節(jié)省內(nèi)存的方式表示信號(hào),讓每一個(gè)二進(jìn)制位來(lái)代表一個(gè)信號(hào),則8個(gè)字節(jié)足夠,而sigset_t本質(zhì)上就是占用128個(gè)字節(jié),然后采用每一個(gè)二進(jìn)制位表示一個(gè)信號(hào)例子vi 07sigset.c/信號(hào)集的概念和基本操作#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;底層的實(shí)現(xiàn)方法(2) 基本操作#include <signal.h> sigemptyset() - 清空信號(hào)集(二進(jìn)制置為0) sigfillset() - 填滿信號(hào)集(二進(jìn)制置為1) sigaddset() - 增加一個(gè)信號(hào)(對(duì)應(yīng)二進(jìn)制置為1) sigdelset() - 刪除一個(gè)信號(hào)(對(duì)應(yīng)二進(jìn)制置為0) sigismember() - 查找是否存在某個(gè)信號(hào) 例子:/信號(hào)集的概念和基本操作#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;/先定義信號(hào)集 printf("set=%ld",set); /清空信號(hào)集 sigemptyset(&set); printf("set=%ld",set); /增加信號(hào)到信號(hào)集中,第二位二進(jìn)制置為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("信號(hào)3存在信號(hào)集中n"); i

24、f(sigsimumber(&set,7) printf("信號(hào)7存在信號(hào)集中n"); return 0;因?yàn)槭莝et是sigset_t類型,不是long int類型.這里為了省事這么輸出2.9 信號(hào)的屏蔽 在某些特殊情況下不允許程序的執(zhí)行被信號(hào)打斷,則需要對(duì)信號(hào)進(jìn)行屏蔽來(lái)解決此問(wèn)題(1)sigprocmask函數(shù) (examine and change blocked signals(信號(hào)集) #include <signal.h> int sigprocmask(int how, const sigset_t* set, sigset_t *olds

25、et);第一個(gè)參數(shù):處理方式 SIG_BLOCK: ABC CDE =>ABCDE(新+舊) SIG_UNBLOCK: ABC CDE=>AB(舊-新) SIG_SETMASK: ABC CDE=>CDE(新的替換舊的,掌握)第二個(gè)參數(shù):設(shè)置新的信號(hào)屏蔽字(信號(hào)集)第三個(gè)參數(shù):帶出舊的信號(hào)屏蔽字(信號(hào)集)函數(shù)功能:主要用于設(shè)置新的信號(hào)屏蔽字,帶出之前的信號(hào)屏蔽字(2)sigpending 函數(shù)#include <signal>int sigpending(sigset_t *set); 函數(shù)功能:獲取在信號(hào)屏蔽期間來(lái)過(guò)的信號(hào)例子:/sigprocmask函數(shù)的使用

26、#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>#include <sys/types.h>void fa(int signo) printf("捕獲到了信號(hào)%dn",signo);int main(void) printf("當(dāng)前進(jìn)程的進(jìn)程號(hào)%dn",getpid(); /設(shè)置對(duì)信號(hào)2,信號(hào)3,信號(hào)50進(jìn)行自定義處理 signal(2,fa); signal(3,fa); signal(50,fa); int res=sleep(20);/返回未完成的時(shí)間 if(0!=res) printf("沒(méi)有信號(hào)屏蔽,睡眠別喚醒,所以睡了%d秒n",20-res); printf("-n"); printf("開始

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論