信號概念
不存在編號為0的信號。
產(chǎn)生信號的方式:
1??????????當(dāng)用戶按某些終端鍵時,引發(fā)終端產(chǎn)生信號。
2??????????硬件異常產(chǎn)生信號,比如SIGSEGV信號。
3??????????進程調(diào)用kill函數(shù)可將信號發(fā)送給另外一個進程或者進程組。
4??????????當(dāng)檢測到某種條件發(fā)生時,并應(yīng)將其通知有關(guān)進程時也產(chǎn)生信號。比如SIGPIPE信號。
應(yīng)用程序?qū)Ξa(chǎn)生的信號有三種方式進行處理
1??????????忽略信號
2??????????系統(tǒng)默認(rèn)
3??????????安裝信號處理函數(shù),讓信號處理函數(shù)來處理
?
kill –l 可以查看系統(tǒng)中的信號編號
ubuntu 信號集
?
root@LeoK:~/APUE/8_test# kill -l 1)SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5)SIGTRAP 6)SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10)SIGUSR1 11) SIGSEGV 12)SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20)SIGTSTP 21) SIGTTIN 22)SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28)SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34)SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40)SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45)SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50)SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55)SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60)SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX
?
下列情況是不產(chǎn)生core為
1進程是設(shè)置用戶ID的,而且當(dāng)前用戶并非程序文件的所有者
2進程是設(shè)置了組ID的,而且當(dāng)前用戶并非程序文件的所有者
3用戶沒有寫當(dāng)前用戶的權(quán)限
4該文件太大
?
SIGPIPE信號生成
?
tips:
調(diào)用execl 子進程的信號處理函數(shù)都會被沖掉,使信號處理函數(shù)變成默認(rèn)行為。
當(dāng)一個進程調(diào)用fork的時候,其子進程繼承父進程的信號處理方式
?
?
signal信號安裝函數(shù)
?
typedef void sig_dispose(int sig_no); sig_dispose signal(sig_dispose func1);
?
其中函數(shù)地址可以指定如下宏
?
#ifndef __ASSEMBLY__ typedef void __signalfn_t(int); typedef __signalfn_t *__sighandler_t; typedef void __restorefn_t(void); typedef __restorefn_t *__sigrestore_t; #define SIG_DFL ((__sighandler_t)0) /* default signal handling */ #define SIG_IGN ((__sighandler_t)1) /* ignore signal */ #define SIG_ERR ((__sighandler_t)-1) /* error return from signal */ #endif
?
不可靠信號(博客中有一篇主要講可靠信號和不可靠信號之間的區(qū)別)
?
中斷系統(tǒng)調(diào)用:
對于正在執(zhí)行低速系統(tǒng)調(diào)用的時候,收到信號,那么進程就會捕捉到這個信號,中斷這個低速的系統(tǒng)調(diào)用,并且把errno設(shè)置為EINTR表示被信號中斷了。
可重入函數(shù)
不可重入函數(shù)的原因是api內(nèi)部使用了全局靜態(tài)數(shù)據(jù)結(jié)構(gòu),每一個進程調(diào)用的時候,會寫亂這個全局?jǐn)?shù)據(jù)結(jié)構(gòu),或者api內(nèi)部調(diào)用了malloc或者free在修改鏈表的時候。
?
可靠信號術(shù)語和語義
在信號產(chǎn)生和遞送之間的時間間隔內(nèi),稱信號是未決的。
每一個進程都有一個信號屏蔽字,它規(guī)定了當(dāng)前要阻塞遞送到該進程的信號集,對于每種可能的信號,該屏蔽字都有一位與之相對應(yīng),對于某種信號,若其對應(yīng)位已經(jīng)被設(shè)置則他當(dāng)前是阻塞的
?
?
int kill(pid_t pid, int signo) int raise(int signo);
?
pid 為
>0 ??????????? 向進程pid發(fā)送信號
<0????????????? 向進程為|pid|的進程發(fā)送信號
==0 ???????? 向調(diào)用的進程組中的每一個進程發(fā)送信號。而且有向這些進程發(fā)送信號的權(quán)限。
==-1????????? 向所有進程發(fā)送信號,必須有權(quán)限。
有權(quán)限的定義是:發(fā)送者的實際或者有效用戶ID必須等于接受者的實際或者有效用戶ID
?
alarm和pause新哈皮
?
unsigned int alarm(unsigned int seconds);
?
向進程發(fā)送SIGALRM信號,其默認(rèn)動作是終止該進程
alarm在設(shè)置鬧鐘時間的時候,如果之前進程設(shè)置了另外一個鬧鐘時間,那么alarm就返回之前的剩余值。
如果seconds為0表示取消以前的鬧鐘
?
?
int pause()
?
pause函數(shù)使調(diào)用進程掛起知道捕捉到一個信號,只有執(zhí)行了一個信號處理程序,并從中返回,pause才會返回。
?
信號集
sigset_t 表示信號集
函數(shù)
?
int sigemptyset(sigset_t *set); int sigfillset(sigset_t* set); int sigaddset(sigset_t *set, int signo); int sigdeleteset(sigset_t* set, int signo); int sigismember(const sigset_t* set, intsigno):
?
設(shè)置信號屏蔽字
?
int sigprocmask(int how, constsigset_t *set, sigset_t *oset);
?
h
ow:用于指定信號修改的方式,可能選擇有三種
SIG_BLOCK //加入信號到進程屏蔽。
SIG_UNBLOCK //從進程屏蔽里將信號刪除。
SIG_SETMASK //將set的值設(shè)定為新的進程屏蔽。
?
查看當(dāng)前進程中未決的信號
int sigpending(sigset_t *set),在set中獲取當(dāng)前進程未決的信號集類型
?
sigaction函數(shù)的功能是檢查或修改與指定信號相關(guān)聯(lián)的處理動作(可同時兩種操作)。
他是POSIX的信號接口,而signal()是標(biāo)準(zhǔn)C的信號接口(如果程序必須在非POSIX系統(tǒng)上運行,那么就應(yīng)該使用這個接口)
給信號signum設(shè)置新的信號處理函數(shù)act,同時保留該信號原有的信號處理函數(shù)oldact
int?sigaction(int?signo,const?struct?sigaction?*restrict act, ??????????????struct?sigaction?*restrict oact); |
結(jié)構(gòu)sigaction定義如下:
struct?sigaction{
|
sa_handler字段包含一個信號捕捉函數(shù)的地址
sa_mask字段說明了一個信號集,在調(diào)用該信號捕捉函數(shù)之前,這一信號集要加進進程的信號屏蔽字中。僅當(dāng)從信號捕捉函數(shù)返回時再將進程的信號屏蔽字復(fù)位為原先值。
sa_flag是一個選項,主要理解兩個
SA_INTERRUPT 由此信號中斷的系統(tǒng)調(diào)用不會自動重啟
SA_SIGINFO 提供附加信息,一個指向siginfo結(jié)構(gòu)的指針以及一個指向進程上下文標(biāo)識符的指針 |
?
?
sigsetjmp和siglongjmp
1. 原型 :
?
#include <setjmp.h> int sigsetjmp(sigjmp_buf env, int savemask);
直接調(diào)用則返回0,?從siglongjmp調(diào)用返回則返回非0值.
void?siglongjmp(sigjmp_buf?env,?int?val);
?
可見發(fā)現(xiàn)sigsetjmp比setjmp多了一個參數(shù)savemask, 如果非0, 則sigsetjmp在env中保存進程的當(dāng)前信號屏蔽字
?
sigsuspend函數(shù)
?
#include <signal.h> int sigsuspend(const sigset_t *sigmask)
?
也就是說, sigsuspend后,進程就掛在那里,等待著開放的信號的喚醒 。系統(tǒng)在接受到信號后,馬上就把現(xiàn)在的信號集還原為原來的,然后調(diào)用處理函數(shù)。
?
void abot()函數(shù)向進程發(fā)送SIGABRT信號
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
