信號概念
不存在編號為0的信號。
產生信號的方式:
1??????????當用戶按某些終端鍵時,引發終端產生信號。
2??????????硬件異常產生信號,比如SIGSEGV信號。
3??????????進程調用kill函數可將信號發送給另外一個進程或者進程組。
4??????????當檢測到某種條件發生時,并應將其通知有關進程時也產生信號。比如SIGPIPE信號。
應用程序對產生的信號有三種方式進行處理
1??????????忽略信號
2??????????系統默認
3??????????安裝信號處理函數,讓信號處理函數來處理
?
kill –l 可以查看系統中的信號編號
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
?
下列情況是不產生core為
1進程是設置用戶ID的,而且當前用戶并非程序文件的所有者
2進程是設置了組ID的,而且當前用戶并非程序文件的所有者
3用戶沒有寫當前用戶的權限
4該文件太大
?
SIGPIPE信號生成
?
tips:
調用execl 子進程的信號處理函數都會被沖掉,使信號處理函數變成默認行為。
當一個進程調用fork的時候,其子進程繼承父進程的信號處理方式
?
?
signal信號安裝函數
?
typedef void sig_dispose(int sig_no); sig_dispose signal(sig_dispose func1);
?
其中函數地址可以指定如下宏
?
#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
?
不可靠信號(博客中有一篇主要講可靠信號和不可靠信號之間的區別)
?
中斷系統調用:
對于正在執行低速系統調用的時候,收到信號,那么進程就會捕捉到這個信號,中斷這個低速的系統調用,并且把errno設置為EINTR表示被信號中斷了。
可重入函數
不可重入函數的原因是api內部使用了全局靜態數據結構,每一個進程調用的時候,會寫亂這個全局數據結構,或者api內部調用了malloc或者free在修改鏈表的時候。
?
可靠信號術語和語義
在信號產生和遞送之間的時間間隔內,稱信號是未決的。
每一個進程都有一個信號屏蔽字,它規定了當前要阻塞遞送到該進程的信號集,對于每種可能的信號,該屏蔽字都有一位與之相對應,對于某種信號,若其對應位已經被設置則他當前是阻塞的
?
?
int kill(pid_t pid, int signo) int raise(int signo);
?
pid 為
>0 ??????????? 向進程pid發送信號
<0????????????? 向進程為|pid|的進程發送信號
==0 ???????? 向調用的進程組中的每一個進程發送信號。而且有向這些進程發送信號的權限。
==-1????????? 向所有進程發送信號,必須有權限。
有權限的定義是:發送者的實際或者有效用戶ID必須等于接受者的實際或者有效用戶ID
?
alarm和pause新哈皮
?
unsigned int alarm(unsigned int seconds);
?
向進程發送SIGALRM信號,其默認動作是終止該進程
alarm在設置鬧鐘時間的時候,如果之前進程設置了另外一個鬧鐘時間,那么alarm就返回之前的剩余值。
如果seconds為0表示取消以前的鬧鐘
?
?
int pause()
?
pause函數使調用進程掛起知道捕捉到一個信號,只有執行了一個信號處理程序,并從中返回,pause才會返回。
?
信號集
sigset_t 表示信號集
函數
?
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):
?
設置信號屏蔽字
?
int sigprocmask(int how, constsigset_t *set, sigset_t *oset);
?
h
ow:用于指定信號修改的方式,可能選擇有三種
SIG_BLOCK //加入信號到進程屏蔽。
SIG_UNBLOCK //從進程屏蔽里將信號刪除。
SIG_SETMASK //將set的值設定為新的進程屏蔽。
?
查看當前進程中未決的信號
int sigpending(sigset_t *set),在set中獲取當前進程未決的信號集類型
?
sigaction函數的功能是檢查或修改與指定信號相關聯的處理動作(可同時兩種操作)。
他是POSIX的信號接口,而signal()是標準C的信號接口(如果程序必須在非POSIX系統上運行,那么就應該使用這個接口)
給信號signum設置新的信號處理函數act,同時保留該信號原有的信號處理函數oldact
int?sigaction(int?signo,const?struct?sigaction?*restrict act, ??????????????struct?sigaction?*restrict oact); |
結構sigaction定義如下:
struct?sigaction{
|
sa_handler字段包含一個信號捕捉函數的地址
sa_mask字段說明了一個信號集,在調用該信號捕捉函數之前,這一信號集要加進進程的信號屏蔽字中。僅當從信號捕捉函數返回時再將進程的信號屏蔽字復位為原先值。
sa_flag是一個選項,主要理解兩個
SA_INTERRUPT 由此信號中斷的系統調用不會自動重啟
SA_SIGINFO 提供附加信息,一個指向siginfo結構的指針以及一個指向進程上下文標識符的指針 |
?
?
sigsetjmp和siglongjmp
1. 原型 :
?
#include <setjmp.h> int sigsetjmp(sigjmp_buf env, int savemask);
直接調用則返回0,?從siglongjmp調用返回則返回非0值.
void?siglongjmp(sigjmp_buf?env,?int?val);
?
可見發現sigsetjmp比setjmp多了一個參數savemask, 如果非0, 則sigsetjmp在env中保存進程的當前信號屏蔽字
?
sigsuspend函數
?
#include <signal.h> int sigsuspend(const sigset_t *sigmask)
?
也就是說, sigsuspend后,進程就掛在那里,等待著開放的信號的喚醒 。系統在接受到信號后,馬上就把現在的信號集還原為原來的,然后調用處理函數。
?
void abot()函數向進程發送SIGABRT信號
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

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