UNIX环境编程学习笔记(25)——信号处理进阶学习之 sigaction 函数
lienhua34
2014-11-05
sigaction 函數跟 signal 函數一樣,用于設置信號處理函數。此函數是用于取代 UNIX 早期版本使用的 signal 函數。UNIX 早期版本的 signal 函數在捕獲到一個信號之后,就會自動將該信號的處理動作恢復為默認處理動作。于是,如果我們希望注冊的信號處理函數長期生效,則需要在信號處理程序中再次調用 signal 函數注冊一次。這樣的操作太麻煩,而且在信號處理函數中再次調用 signal 注冊信號處理函數之前可能又會產生該信號,而這個信號就會觸發默認處理動作。
另外,signal 函數還有一個限制:不修改信號的處理方式就不能確定該信號的當前處理方式。這個限制在 sigaction 函數中不存在。
sigaction 函數的聲明如下,
#include <signal.h>
int sigaction(int signo, const struct sigaction *restrict act, struct sigaction *restrict oact);
返回值:若成功則返回0,若出錯則返回-1
其中,signo 參數即要檢測或修改其處理動作的信號編號。如果 act 指針非空,則要修改該信號的處理動作。如果 oact 指針非空,則由 oact 指針返回該信號的上一個動作。
sigaction 函數的參數中使用的結構體 struct sigaction 的聲明如下,
該結構體各個字段的說明如下:
- sa_handler:信號處理函數的指針。
- sa_mask:在調用該信號的處理函數期間進程要阻塞的信號集。
- sa_flags:指定信號進行處理的各個選項,關于具體的選項,可以參考sigaction 函數的手冊。
- sa_sigaction:替代的信號處理函數,如果sa_flags 設置了SA_SIGINFO,則會調用該信號處理函數;否則調用sa_handler。
我們來看一個例子,
#include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <errno.h> #include <signal.h>void print_mask(const char *str) {sigset_t sigset;int errno_save;errno_save = errno;if (sigprocmask(0, NULL, &sigset) < 0) {printf("sigprocmask error: %s\n", strerror(errno));exit(-1);}printf("%s", str);if (sigismember(&sigset, SIGALRM)) {printf("SIGALRM ");}if (sigismember(&sigset, SIGINT)) {printf("SIGINT ");}printf("\n");errno = errno_save; }static void sig_alrm(int signo) {printf("received SIGALRM\n");print_mask("in sig_alrm: "); }int main(void) {struct sigaction sact;sact.sa_handler = sig_alrm;sact.sa_flags = 0;sigemptyset(&sact.sa_mask);sigaddset(&sact.sa_mask, SIGINT);if (sigaction(SIGALRM, &sact, NULL) < 0) {printf("sigaction error: %s\n", strerror(errno));exit(-1);}print_mask("in main before alarm: ");alarm(3);pause();print_mask("in main after alarm: ");exit(0); }在上面的 sigactiondemo.c 程序中,我們調用 sigaction 函數設置了信號 SIGALRM 的處理函數,而在 sigaction 函數的參數 act 的sa_mask 字段中添加了信號 SIGINT,表示調用信號 SIGALRM 的處理函數期間,進程阻塞信號 SIGINT。編譯該程序,生成并執行可執行文件 sigactiondemo,
lienhua34:demo$ gcc -o sigactiondemo sigactiondemo.c lienhua34:demo$ ./sigactiondemo in main before alarm: received SIGALRM in sig_alrm: SIGALRM SIGINT in main after alarm:從上面的運行結果,我們看到在 SIGALRM 信號產生之前,進程沒有屏蔽信號 SIGINT 和 SIGALRM,而在信號 SIGALRM 的處理函數中,進程的信號屏蔽字中包含了 SIGINT 和 SIGALRM,而在調用 SIGALRM 的信號處理函數之后,進程的信號屏蔽字復原為調用信號處理屏蔽字之前。(說明:在調用 sigaction 函數注冊的信號處理函數期間,系統會自動將該信號也加入信號屏蔽字中,除非設置 sigaction 函數的 act 參數的sa_flags為SA_NODEFER。)
(done)
轉載于:https://www.cnblogs.com/lienhua34/p/4077595.html
總結
以上是生活随笔為你收集整理的UNIX环境编程学习笔记(25)——信号处理进阶学习之 sigaction 函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ANT下载和配置
- 下一篇: 混沌分形之逻辑斯蒂(Logistic)映