Linux處理序間通訊——訊號集合函式

來源:互聯網
上載者:User
我們已經知道,我們可以通過訊號來終止進程,也可以通過訊號來在進程間進行通訊,程式也可以通過指定訊號的關聯處理函數來改變訊號的預設處理方式,也可以屏蔽某些訊號,使其不能傳遞給進程。那麼我們應該如何設定我們需要處理的訊號,我們不需要處理哪些訊號等問題呢?訊號集合函式就是協助我們解決這些問題的。有關Linux進程間使用訊號通訊的更多內容,可以參閱我的另一篇文章——Linux處理序間通訊——使用訊號下面是訊號函數集:1、int sigemptyset(sigset_t *set);該函數的作用是將訊號集初始化為空白。2、int sigfillset(sigset_t *set);該函數的作用是把訊號集初始化包含所有已定義的訊號。3、int sigaddset(sigset_t *set, int signo);該函數的作用是把訊號signo添加到訊號集set中,成功時返回0,失敗時返回-1。4、int sigdelset(sigset_t *set, int signo);該函數的作用是把訊號signo從訊號集set中刪除,成功時返回0,失敗時返回-1.5、int sigismember(sigset_t *set, int signo);該函數的作用是判斷給定的訊號signo是否是訊號集中的一個成員,如果是返回1,如果不是,返回0,如果給定的訊號無效,返回-1;6、int sigpromask(int how, const sigset_t *set, sigset_t *oset);該函數可以根據參數指定的方法修改進程的訊號屏蔽字。新的訊號屏蔽字由參數set(非空)指定,而原先的訊號屏蔽字將儲存在oset(非空)中。如果set為空白,則how沒有意義,但此時調用該函數,如果oset不為空白,則把當前訊號屏蔽字儲存到oset中。how的不同取值及操作如下所示:如果sigpromask成功完成返回0,如果how取值無效返回-1,並設定errno為EINVAL。注意:調用這個函數才能改變進程的屏蔽字,之前的函數都是為改變一個變數的值而已,並不會真正影響進程的屏蔽字。7、int sigpending(sigset_t *set);該函數的作用是將被阻塞的訊號中停留在待處理狀態的一組訊號寫到參數set指向的訊號集中,成功調用返回0,否則返回-1,並設定errno表明錯誤原因。8、int sigsuspend(const sigset_t *sigmask);該函數通過將進程的屏蔽字替換為由參數sigmask給出的訊號集,然後掛起進程的執行。注意操作的先後順序,是先替換再掛起程式的執行。程式將在訊號處理函數執行完畢後繼續執行。如果接收到訊號終止了程式,sigsuspend就不會返回,如果接收到的訊號沒有終止程式,sigsuspend就返回-1,並將errno設定為EINTR。特別提醒:如果一個訊號被進程阻塞,它就不會傳遞給進程,但會停留在待處理狀態,當進程解除對待處理訊號的阻塞時,待處理訊號就會立刻被處理。下面以一個例子來說明上述函數的用法,源檔案為sigset.c,代碼如下:
#include <unistd.h>#include <signal.h>#include <sys/types.h>#include <stdlib.h>#include <stdio.h>void handler(int sig){printf("Handle the signal %d\n", sig);}int main(){sigset_t sigset;//用於記錄屏蔽字sigset_t ign;//用於記錄被阻塞的訊號集struct sigaction act;//清空訊號集sigemptyset(&sigset);sigemptyset(&ign);//向訊號集中添加訊號SIGINTsigaddset(&sigset, SIGINT);//設定處理函數和訊號集act.sa_handler = handler;sigemptyset(&act.sa_mask);act.sa_flags = 0;sigaction(SIGINT, &act, 0);printf("Wait the signal SIGINT...\n");pause();//掛起進程,等待訊號//設定進程屏蔽字,在本例中為屏蔽SIGINTsigprocmask(SIG_SETMASK, &sigset, 0);printf("Please press Ctrl+c in 10 seconds...\n");sleep(10);//測試SIGINT是否被屏蔽sigpending(&ign);if(sigismember(&ign, SIGINT))printf("The SIGINT signal has ignored\n");//在訊號集中刪除訊號SIGINTsigdelset(&sigset, SIGINT);printf("Wait the signal SIGINT...\n");//將進程的屏蔽字重新設定,即取消對SIGINT的屏蔽//並掛起進程sigsuspend(&sigset);printf("The app will exit in 5 seconds!\n");sleep(5);exit(0);}
運行結果如下:首先,我們能過sigaction函數改變了SIGINT訊號的預設行為,使之執行指定的函數handler,所以輸出了語句:Handle the signal 2。然後,通過sigprocmask設定進程的訊號屏蔽字,把SIGINT訊號屏蔽起來,所以過了10秒之後,用sigpending函數去擷取被阻塞的訊號集時,檢測到了被阻塞的訊號SIGINT,輸出The SIGINT signal
has ignored。最後,用函數sigdelset函數去除先前用sigaddset函數加在sigset上的訊號SIGINT,再調用函數sigsuspend,把進程的屏蔽字再次修改為sigset(不包含SIGINT),並掛起進程。由於先前的SIGINT訊號停留在待處理狀態,而現在進程已經不再阻塞該訊號,所以進程馬上對該訊號進行處理,從而在最後,你不用輸入Ctrl+c也會出現後面的處理語句(可參閱前面特別提醒的內容),最後過了5秒程式就成功退出了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.