久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久


信號處理函數signal()和信號集函數組

分享到:
           

    本文關鍵字: 信號處理函數,signal(),信號集函數組

    信(xin)號處理(li)的(de)方(fang)法主要有兩(liang)種(zhong)(zhong),一種(zhong)(zhong)是使(shi)用(yong)signal()函數,另一種(zhong)(zhong)是使(shi)用(yong)信(xin)號集(ji)函數組。下面分別介紹(shao)這兩(liang)種(zhong)(zhong)處理(li)方(fang)式。

    1)使用signal()函數

    使(shi)(shi)(shi)用(yong)signal()函數處理(li)時,只(zhi)需指出要(yao)處理(li)的(de)信號(hao)和處理(li)函數即可(ke)。它主(zhu)要(yao)用(yong)于(yu)(yu)前32種非實時信號(hao)的(de)處理(li),不支(zhi)持信號(hao)傳遞信息(xi),但是由于(yu)(yu)使(shi)(shi)(shi)用(yong)簡(jian)單、易于(yu)(yu)理(li)解,因此也受到(dao)很多(duo)程序員的(de)歡迎。Linux還支(zhi)持一個更健壯更新的(de)信號(hao)處理(li)函數sigaction(),推薦使(shi)(shi)(shi)用(yong)該函數。

    signal()函數的語法(fa)要點(dian)如(ru)表1所(suo)示。

表1 signal()函數語法要點

所需頭文件 #include <signal.h>
函數原型 typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
函數傳入值 signum:指定信號代碼
handler SIG_IGN:忽略該信號
SIG_DFL:采用系統默認方式處理信號
自定義的信號處理函數指針
函數返回值 成功:以前的信號處理配置
出錯:-1

    這里需要對該函數(shu)原型(xing)(xing)進行說明(ming)。這個函數(shu)原型(xing)(xing)有(you)點復雜:首先該函數(shu)原型(xing)(xing)整體(ti)指(zhi)(zhi)向一個無(wu)返回值并且帶(dai)一個整型(xing)(xing)參(can)(can)數(shu)的函數(shu)指(zhi)(zhi)針(zhen),也就是信號(hao)的原始配置(zhi)函數(shu);接著該原型(xing)(xing)又帶(dai)有(you)兩(liang)個參(can)(can)數(shu),其中第2個參(can)(can)數(shu)可以是用戶(hu)自定(ding)義的信號(hao)處(chu)理函數(shu)的函數(shu)指(zhi)(zhi)針(zhen)。

 &nbsp;  表2列(lie)舉了sigaction()函(han)數的語法(fa)要點。

表2 sigaction()函數語法要點

所需頭文件 #include <signal.h>
函數原型 int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
函數傳入值 signum:信號代碼,可以為除SIGKILL及SIGSTOP外的任何一個特定有效的信號
act:指向結構sigaction的一個實例的指針,指定對特定信號的處理
oldact:保存原來對相應信號的處理
函數返回值 成功:0
出錯:-1

    這里要說明的是sigaction()函(han)數(shu)中第2和第3個(ge)(ge)參數(shu)用到(dao)的sigaction結(jie)構,這是一個(ge)(ge)看似(si)非(fei)常復雜的結(jie)構,希(xi)望讀者能夠慢(man)慢(man)閱讀此(ci)段(duan)內容(rong)。

   ; 首先給出了sigaction的(de)定義,代碼如下:

    struct sigaction
    {
        void (*sa_handler)(int signo);
        sigset_t sa_mask;
        int sa_flags;
        void (*sa_restore)(void);
    }

    sa_handler是(shi)一(yi)個函(han)(han)數指(zhi)針,指(zhi)定信(xin)號(hao)處(chu)理(li)函(han)(han)數,這(zhe)里除可以是(shi)用戶自定義的(de)處(chu)理(li)函(han)(han)數外,還可以為SIG_DFL(采用默認的(de)處(chu)理(li)方式)或SIG_IGN(忽略(lve)信(xin)號(hao))。它的(de)處(chu)理(li)函(han)(han)數只有一(yi)個參數,即信(xin)號(hao)值。

    sa_mask是一個信(xin)號(hao)(hao)集(ji),它可(ke)以指定在信(xin)號(hao)(hao)處理程(cheng)序執行過(guo)程(cheng)中(zhong)哪些信(xin)號(hao)(hao)應當被屏蔽,在調(diao)用信(xin)號(hao)(hao)捕獲函數前(qian),該(gai)信(xin)號(hao)(hao)集(ji)要加入(ru)到信(xin)號(hao)(hao)的信(xin)號(hao)(hao)屏蔽字(zi)中(zhong)。

 ;   sa_flags中包(bao)含(han)了(le)許(xu)多標志位,是對信號進行(xing)處(chu)理的(de)各(ge)個選(xuan)擇項。它的(de)常見可選(xuan)值如表3所(suo)示。

表3 常見信號的(de)含義及(ji)其默認操作

信 號 含 義
SA_NODEFER / SA_NOMASK 當捕捉到此信號時,在執行其信號捕捉函數時,系統不會自動屏蔽此信號
SA_NOCLDSTOP 進程忽略子進程產生的任何SIGSTOP、SIGTSTP、SIGTTIN和SIGTTOU信號
SA_RESTART 令重啟的系統調用起作用
SA_ONESHOT / SA_RESETHAND 自定義信號只執行一次,在執行完畢后恢復信號的系統默認動作

  &nbsp; 以下實例表(biao)明了如何(he)使用signal()函(han)(han)數捕捉(zhuo)相(xiang)應(ying)信號(hao),并做(zuo)出(chu)給定的(de)處理。這里,my_func就是信號(hao)處理的(de)函(han)(han)數指針,讀(du)者還可以將其改為SIG_IGN或SIG_DFL查看運行結果(guo)。第2個實例是用sigaction()函(han)(han)數實現同樣的(de)功能。

    以(yi)下(xia)是使用signal()函數的示例:

    /* signal.c */
    #include <signal.h>
    #include <stdio.h>
    #include <stdlib.h>

    /* 自定義信號處理函數 */
    void my_func(int sign_no)
    {
        if (sign_no == SIGINT)
        {
            printf("I have get SIGINT\n");
        }
        else if (sign_no == SIGQUIT)
        {
            printf("I have get SIGQUIT\n");
        }
    }

    int main()
    {
        printf("Waiting for signal SIGINT or SIGQUIT...\n");

        /* 發出相應的信號,并跳轉到信號處理函數處 */
        signal(SIGINT, my_func);
        signal(SIGQUIT, my_func);
        pause();
        exit(0);
    }

    運行(xing)結(jie)果(guo)如下:

    $ ./signal
    Waiting for signal SIGINT or SIGQUIT...
    I have get SIGINT (按Ctrl+c 組合鍵)
    $ ./signal
    Waiting for signal SIGINT or SIGQUIT...
    I have get SIGQUIT (按(an)Ctrl+\ 組合鍵)

    以下是(shi)用sigaction()函數實現同樣的功能,只列(lie)出(chu)了(le)更(geng)新的main()函數部(bu)分。

    /* sigaction.c */
    /* 前部分省略 */
    int main()
    {
        struct sigaction action;
        printf("Waiting for signal SIGINT or SIGQUIT...\n");

        /* sigaction結構初始化 */
        action.sa_handler = my_func;
        sigemptyset(&action.sa_mask);
        action.sa_flags = 0;

        /* 發出相應的信號,并跳轉到信號處理函數處 */
        sigaction(SIGINT, &action, 0);
        sigaction(SIGQUIT, &action, 0);
        pause();
        exit(0);
    }

    2)信號(hao)集(ji)函(han)數組

 &nbsp;  使用信(xin)(xin)號集函(han)(han)數(shu)組處(chu)理信(xin)(xin)號時涉及一系列的函(han)(han)數(shu),這些(xie)函(han)(han)數(shu)按照(zhao)調(diao)用的先后次序可分為以下幾大功能(neng)模塊:創建信(xin)(xin)號集、注冊信(xin)(xin)號處(chu)理函(han)(han)數(shu)及檢(jian)測(ce)信(xin)(xin)號。

  &nbsp; 其中,創(chuang)建信號(hao)集主要用(yong)(yong)于處理用(yong)(yong)戶感興趣的一些信號(hao),其函(han)數包括以下幾個。

  &nbsp; ● sigemptyset():將信(xin)號集(ji)初(chu)始(shi)化為空。

&nbsp;   ● sigfillset():將信號集(ji)初始化為包含所有已定義(yi)的信號集(ji)。

    ● sigaddset():將指定信號加入到(dao)信號集中。

    ● sigdelset():將指定信(xin)號(hao)從信(xin)號(hao)集中刪除。

    ●&nbsp;sigismember():查詢(xun)指定信號(hao)是否在信號(hao)集中。

    注冊信(xin)號(hao)(hao)(hao)(hao)(hao)處理函數主(zhu)要(yao)用(yong)(yong)于決定進(jin)(jin)程(cheng)如何處理信(xin)號(hao)(hao)(hao)(hao)(hao)。這里要(yao)注意的(de)是(shi),信(xin)號(hao)(hao)(hao)(hao)(hao)集里的(de)信(xin)號(hao)(hao)(hao)(hao)(hao)并不是(shi)真正可以處理的(de)信(xin)號(hao)(hao)(hao)(hao)(hao),只有當(dang)信(xin)號(hao)(hao)(hao)(hao)(hao)的(de)狀態處于非阻塞(sai)狀態時(shi)才會真正起(qi)作用(yong)(yong)。因(yin)此(ci),首先使用(yong)(yong)sigprocmask()函數檢測并更(geng)改信(xin)號(hao)(hao)(hao)(hao)(hao)屏蔽字(信(xin)號(hao)(hao)(hao)(hao)(hao)屏蔽字是(shi)用(yong)(yong)來(lai)指定當(dang)前被阻塞(sai)的(de)一組信(xin)號(hao)(hao)(hao)(hao)(hao),它們(men)不會被進(jin)(jin)程(cheng)接收),然(ran)后使用(yong)(yong)sigaction()函數來(lai)定義進(jin)(jin)程(cheng)接收到特定信(xin)號(hao)(hao)(hao)(hao)(hao)后的(de)行為。

    檢(jian)(jian)測(ce)信(xin)(xin)號是信(xin)(xin)號處(chu)理(li)(li)的后續步(bu)驟,因(yin)為被阻塞的信(xin)(xin)號不(bu)會傳遞給進(jin)(jin)程,所以這些信(xin)(xin)號就處(chu)于(yu)“未處(chu)理(li)(li)”狀態(也就是進(jin)(jin)程不(bu)清(qing)楚(chu)它的存在)。sigpending()函數允(yun)許進(jin)(jin)程檢(jian)(jian)測(ce)“未處(chu)理(li)(li)”信(xin)(xin)號,并進(jin)(jin)一步(bu)決定對(dui)它們做何處(chu)理(li)(li)。

 &nbsp;  首先介(jie)紹(shao)創建信(xin)號集的函(han)數格式,表4列舉了(le)這一組函(han)數的語法要點。

表4 創建信號(hao)集函數語(yu)法(fa)要點

所需頭文件 #include <signal.h>
函數原型 int sigemptyset(sigset_t *set)
int sigfillset(sigset_t *set)
int sigaddset(sigset_t *set, int signum)
int sigdelset(sigset_t *set, int signum)
int sigismember(sigset_t *set, int signum)
函數傳入值 set:信號集
signum:指定信號代碼
函數返回值 成功:0(sigismember成功返回1,失敗返回0)
出錯:-1

    表5列舉了sigprocmask()函數的語(yu)法要點。

表5 sigprocmask()函(han)數語法要點

所需頭文件 #include <signal.h>
函數原型 int sigprocmask(int how, const sigset_t *set, sigset_t *oset)
函數傳入值 how:決定函數的操作方式 SIG_BLOCK:增加一個信號集到當前進程的阻塞集中
SIG_UNBLOCK:從當前的阻塞集中刪除一個信號集
SIG_SETMASK:將當前的信號集設置為信號阻塞集
set:指定信號集
oset:信號屏蔽字
函數返回值 成功:0
出錯:-1

  ;  此(ci)處,若set是一個(ge)非(fei)空指針,則(ze)參數(shu)how表示函數(shu)的操作方(fang)式;若how為(wei)空,則(ze)表示忽略此(ci)操作。

    表6列舉了sigpending()函數的語法要點。

表6 sigpending()函數語法要(yao)點

所需頭文件 #include <signal.h>
函數原型 int sigpending(sigset_t *set)
函數傳入值 set:要檢測的信號集
函數返回值 成功:0
出錯:-1

&nbsp;  &nbsp;總(zong)之(zhi),在處理信號時(shi),一般遵循(xun)如圖1所示的操作(zuo)流程(cheng)。


圖1 一般的信號操作處理流程

    本文選自華清遠見嵌入式培訓教材《從實踐中學嵌入式Linux應用程序開發》

   熱(re)點鏈(lian)接:

   1、信號捕捉函數alarm()和pause()
   2、信號發送函數kill()和raise()
   3、Linux下的信號機制
   4、有名管道(FIFO)
   5、標準流管道

更多新聞>>