信號(hào):
信號(hào)是組概念,發(fā)送方和接收方需要配對存在,比如進(jìn)程A發(fā)送信號(hào)X給進(jìn)程B,進(jìn)程B接收信號(hào)按信號(hào)處理函數(shù)進(jìn)行響應(yīng),具體的處理流程是:
1.1 用戶按下Ctrl-C,這個(gè)鍵盤輸入產(chǎn)生一個(gè)硬件中斷。
1.2 該進(jìn)程的用戶空間代碼暫停執(zhí)行,CPU從用戶態(tài)切換到內(nèi)核態(tài)處理硬件中斷。
1.3 終端驅(qū)動(dòng)程序?qū)trl-C解釋成一個(gè)SIGINT信號(hào),記在該進(jìn)程的PCB中(也可以說發(fā)送了一個(gè)SIGINT信號(hào)給該進(jìn)程)。
1.4 內(nèi)核返回到該進(jìn)程的用戶空間代碼繼續(xù)執(zhí)行之前,首先處理PCB中記錄的信號(hào),發(fā)現(xiàn)有一個(gè)SIGINT信號(hào)待處理,而這個(gè)信號(hào)的默認(rèn)處理動(dòng)作是終止進(jìn)程,所以直接終止進(jìn)程而不再返回它的用戶空間代碼執(zhí)行。
2. 信號(hào)集有哪些?
kill -l && man 7 signal
3. 觸發(fā)信號(hào)的常用操作
Ctrl-C SIGINT
Ctrl-\ SIGQUI
Ctrl-Z SIGTSTP
kill -l USERSIG PID
4. 相關(guān)AP
I//為信號(hào)設(shè)置處理方法
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);//sigprocmask, rt_sigprocmask - examine and change blocked signals
//為進(jìn)程添加阻塞信號(hào)集,表示進(jìn)程接收到其中的信號(hào)并不立即處理,而是等到進(jìn)程解除阻塞后再處理
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);//添加信號(hào)到信號(hào)集中int sigaddset(sigset_t *set, int signum);//從信號(hào)集中刪除信號(hào)int sigdelset(sigset_t *set, int signum);
//判斷信號(hào)是否是信號(hào)集中元素?
int sigismember(const sigset_t *set, int signum);
5. struct sigaction之sa_mask與sa_mask
struct sigaction {?
?void (*sa_handler)(int);?
?void (*sa_sigaction)(int, siginfo_t *, void *);?
?sigset_t sa_mask;?
?int sa_flags;?
?void (*sa_restorer)(void);};
sa_mask是信號(hào)阻塞集sa_flags是信號(hào)修改標(biāo)志
6. 代碼
#include <stdio.h>
#include <signal.h>
void
main(int argc, char *argv[])
{
? ? ? ? struct sigaction act;
? ? ? ? sigemptyset(&act.sa_mask);
? ? ? ? act.sa_flags = 0;
? ? ? ? act.sa_handler = sig_int_handler;
? ? ? ? sigaction(SIGINT, &act, NULL);
? ? ? ? sleep(3);
? ? ? ? printf("Sample for signal programming end\n");
}
void
sig_int_handler(int signum)
{
? ? ? ? printf("Got a signal of %d\n", signum);
}