1. 信號在產生後的三種情況:
1. 阻塞 (blok),進程可以選擇阻塞(blok)某個信號,被阻塞的信號,在產生後將保持未決狀態,直到阻塞被解除,纔有可能抵達該信號。
2. 未決(pending)信號從產生到遞達之間的狀態,就是未決狀態,
3. 處理 (信號的遞達delivery):
信號的處理三種方式:
1. 執行該信號的默認處理方式(如2號信號默認退出程序)
2.忽略此信號(不是阻塞該信號,阻塞是信號沒被處理裏之前的狀態)
3.自定義動作(信號的捕捉)可用函數:signal()或者sigaction()
1. 1號信號SIGHUP信號未阻塞也未產⽣生過,當它遞達時執⾏行默認處理動作。
2. 2號信號SIGINT信號產⽣生過,但正在被阻塞,所以暫時不能遞達(在此之間爲未決狀態)。雖然它的處理動作是忽略,但在沒有解除阻塞之前不能忽略這個信號,因爲進程仍有機會改變處理動作之後再解除阻塞。
3. 3號信號SIGQUIT信號未產⽣生過,⼀一旦產⽣生SIGQUIT信號將被阻塞,它的處理動作是⽤用戶⾃自定義函數sighandler。
2.測試信號屏蔽與解除並抵達
#include<stdio.h>
#include<signal.h>
void showpending(sigset_t *pending)//顯示pending表的位圖
{
int i = 1;
for( ;i<=31; i++)
{
if(sigismember(pending, i))//
printf("1");//1表示信號產生,並處於未決狀態
else
printf("0");//0表示沒有信號產生
}
printf("\n");
}
void handler(int sig)//自定義信號處理方式
{
printf("get a sig :%d",sig);
}
int main()
{
signal(2, handler);//對號信號的捕捉
sigset_t bset, obset;
sigemptyset(&bset);
sigemptyset(&obset);
sigaddset(&bset, 2);
sigprocmask(SIG_SETMASK,&bset, &obset);//屏蔽2號信號
sigset_t pending;//建立屏蔽信號表
int i = 0;
while(1){
sigpending(&pending);獲取信號pending表
showpending(&pending);打印信號pending表
sleep(1);
if(i++ == 10)
{
printf("recover sig block\n");
sigprocmask(SIG_SETMASK, &obset, NULL);//10秒後解除對2號信號的屏蔽
}
}
return 0;
}
結果預測:在代碼前臺運行後先是打印31個0:
原因:在代碼運行時沒有信號產生,也就沒有信號處於未決
在ctrl+c 後第二個0變爲1:
原因:ctrl+c產生2號信號發送給前臺進程,又因爲2號信號被阻塞,所以2號信號未決
在10秒後,又變回全0:
原因:11秒後解除對2好信號的阻塞,此時2號信號可遞達在進程從內核態返回用戶態之時。