亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Linux捕捉信號機制之(signal,kill)、(sig

發布時間:2020-07-03 08:26:06 來源:網絡 閱讀:17455 作者:SherryX 欄目:系統運維

linux下公有64個信號,kill -l 查看一下:
Linux捕捉信號機制之(signal,kill)、(sig
可以看到,缺少了32、33兩個未知信號,從這里分界,前面31個信號是不可靠信號,后面的是可靠信號。當進程發生阻塞的時候(一下子發送很多信號),不可靠信號容易丟失。如何去驗證呢?可以在2(不可靠信號)號信號和34(可靠進程)號信號屏蔽期間,不斷向某個進程發送這兩個信號,待解除屏蔽后,觀察是否丟失。這里測試的時候,要注意一下,9-SIGKILL 19-SIGSTOP 31 32 這4個信號是不能被捕獲的,遍歷以下所有信號就可以發現了。
<br>

信號集

首先,講一下信號集,顧名思義,存放信號的集合。
信號集的操作函數有以下幾個,具體使用,后面再說。
Linux捕捉信號機制之(signal,kill)、(sig

signal

第一種是利用signal,kill函數。

       #include < signal.h>
       typedef void (*sighandler_t)(int);
       sighandler_t signal(int signum, sighandler_t handler);

signal()有兩個參數:信號編號和處理函數(sighandler_t是一個函數指針),返回值也是一個sighandler_t類型的,這里返回的是之前的信號處理函數。
信號處理函數是一個帶int參數,返回值為void的函數。handler也可以是兩個特殊的值:SIG_IGN 屏蔽該信號 SIG_DFL 恢復默認行為

       #include < sys/types.h>
       #include < signal.h>
       int kill(pid_t pid, int sig);

kill()的作用是把信號sig發送給進程pid。

#include <signal.h>
 int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

功能:讀取過更改進程的信號屏蔽字。
返回值:成功為0,失敗為-1
參數:如果oset是非空指針,則讀取進程的當前信號屏蔽字通過oset參數傳出(就是將原來的信號屏蔽字備份到oset);set是更改進程的信號屏蔽字,how指示如何修改。how的可選值如下:
Linux捕捉信號機制之(signal,kill)、(sig
代碼如下:

// 3.不可靠信號的丟失
void handler(int no)
{
    printf("received a signal: %d\n",no);
}

int main()
{
    pid_t pid;
    sigset_t set;
    sigset_t oset;
    int i;

    sigemptyset(&set);          //清空
    sigaddset(&set,2);          //添加2號信號
    sigaddset(&set,34);         //添加34號信號
    for(i = 1 ; i <= 64 ; i++)  //查看集合狀態
    {
        if(sigismember(&set,i) == 1)
        {
            printf("1");
        }
        else
        {
            printf("0");
        }
    }
    printf("\n");
    sigprocmask(SIG_SETMASK,&set,&oset);     //將這個集合設置為這個進程的阻塞信號集

    //綁定信號
    signal(2,handler);
    signal(34,handler);

    sleep(50);  //在此期間,向該進程發送多次2、34號信號
    sigprocmask(SIG_SETMASK,&oset,NULL);//解除綁定

    while(1)
    {
    }
    return 0;
}

在另一個終端(20s內),發送信號:
Linux捕捉信號機制之(signal,kill)、(sig
結果,可以看到,不可靠信號,只收到了一次:
Linux捕捉信號機制之(signal,kill)、(sig

sigaction

第二種是sigacton函數。

       #include <signal.h>
       int sigaction(int signum, const struct sigaction *act,
                     struct sigaction *oldact);

功能:用于改變進程接收到特定信號后的行為。
參數:signum 除了SIGKILL 和SIGSTOP(為這兩個信號定義自己的處理函數,將導致信號安裝錯誤);
第二個參數是指向結構sigaction的一個實例的指針,在結構sigaction的實例中,制定了對特定信號的處理,可以為空,進程會以缺省方式對信號處理;
old用來保存原來對信號的處理,可以為NULL。
返回值:成功為0,失敗-1
sigaction結構體

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_handler和sa_sigaction都是自定義信號處理函數,同樣,sa_handler有兩個默認值:SIG_DFL和SIG_IGN。區別在于sa_sigaction是為實時信號而設定的(也支持非實時信號),第二個參數是指向siginfo_t結構的指針,結構中包含信號攜帶的數據值,第三個參數暫時沒有使用(POSIX沒有規范使用該指針的標準);
sa_mask是屏蔽信號集;
sa_flags有以下幾個值:
Linux捕捉信號機制之(signal,kill)、(sig
重點掌握2個:一個是設置為0,表示默認屬性;一個是設置為SA_SIGINFO,那么此時處理函數不再使用sa_handler,而是sa_sigaction.
那么sa_sigaction的結構體參數長什么樣呢?

           siginfo_t {
               int      si_signo;    /* Signal number */
               int      si_errno;    /* An errno value */
               int      si_code;     /* Signal code */
               pid_t    si_pid;      /* Sending process ID */
               uid_t    si_uid;      /* Real user ID of sending process */
               int      si_status;   /* Exit value or signal */
               clock_t  si_utime;    /* User time consumed */
               clock_t  si_stime;    /* System time consumed */
               sigval_t si_value;    /* Signal value */
               int      si_int;      /* POSIX.1b signal */
               void    *si_ptr;      /* POSIX.1b signal */
               void    *si_addr;     /* Memory location which caused fault */

天哪,肯定記不住。不需要記,用到的時候,查一下就好了。
這里掌握兩個,一個是si_signum,不用說了吧,一個是si_value。這是什么?這是在發送信號時攜帶的一個數據,數據類是sigval,這是一個聯合體。

typedef union sigval
 { 
    int sival_int; 
    void *sival_ptr; 
}sigval_t; 

sigqueue函數

  #include < signal.h>
  int sigqueue(pid_t pid, int sig, const union sigval value);

sigqueue()類似于之前的kill()。是用來發送信號的,主要針對有帶參的信號,與sigaction()配合使用。
第三個參數是一個聯合數據結構union sigval,指定了信號傳遞的參數,即通常所說的4字節值。
具體代碼如下:

void handler(int signo,siginfo_t *resdata,void *unknowp)
{
    printf("signo=%d\n",signo);
    printf("return data :%d\n",resdata->si_value.sival_int);
}

int main()
{
    int i = 5;
    pid_t pid = 0;
    pid = fork();
    if(pid == -1)
    {
        perror("create fork");
        return -1;
    }
    else if(pid == 0)
    {
        sleep(1);
        //向父進程發送帶整型數據的信號
        union sigval sigvalue;
        sigvalue.sival_int = 111;
        //發送信號
        while(i--)
        {
            sigqueue(getppid(),2,sigvalue);
            printf("send signal:2 success!\n");
            sigqueue(getppid(),34,sigvalue);
            printf("send signal:34 success!\n");
        }

    }
    else
    {

        struct sigaction act;
        //初始化sa_mask
        sigemptyset(&act.sa_mask);
        act.sa_sigaction=handler;
        //一旦使用了sa_sigaction屬性,那么必須設置sa_flags屬性的值為SA_SIGINFO
        act.sa_flags=SA_SIGINFO;

        //注冊信號
        sigaction(2,&act,NULL);
        sigaction(34,&act,NULL);

    }

    while(1)
    {
    }
}

運行結果:
Linux捕捉信號機制之(signal,kill)、(sig
同樣,可以看到2號信號只收到了1次。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

绵阳市| 广宁县| 眉山市| 博野县| 临湘市| 扎鲁特旗| 吕梁市| 内江市| 宜州市| 彰武县| 柳江县| 宝清县| 新闻| 仙桃市| 延安市| 大连市| 齐河县| 那坡县| 陕西省| 丹凤县| 江华| 盐山县| 永嘉县| 滁州市| 诸暨市| 易门县| 大渡口区| 揭东县| 巴南区| 泉州市| 久治县| 磴口县| 江源县| 琼结县| 松滋市| 博乐市| 确山县| 科技| 朝阳市| 甘泉县| 房产|