信號的產生於處理

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號信號可遞達在進程從內核態返回用戶態之時。

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章