函数signal、sigaction
生活随笔
收集整理的這篇文章主要介紹了
函数signal、sigaction
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
二、函數sigaction
修改信號處理動作(通常在Linux用來注冊一個信號的捕捉函數)
#inlcude<signal.h> int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);參數:
- act:傳入參數,新的處理方式
- oldact:傳出參數,舊的處理方式
分析:
- ?sa_restorer:該元素是過時的,不應該使用, POSIX.1標準將不指定該元素。(棄用)
- sa_sigaction:當sa_flags被指定為SA_SIGINFO標志時,使用該信號處理程序(很少使用)
- sa_handler:指定信號捕捉后的處理函數名(即注冊函數)。可賦值為SIG_IGN表忽略或SIG_DFL表執行默認動作
- sa_mask:調用信號處理函數時,所要屏蔽的信號集合(信號屏蔽字)。注意僅在處理函數調用期間屏蔽。(默認屬性:信號捕捉函數執行期間,自動屏蔽本信號)
- sa_flag:通常設置為0,表默認屬性
?
1. 測試代碼:
#include<stdio.h> #include<signal.h> #include<stdlib.h> #include<unistd.h>void docatch(int signo) {printf("%d signal is catch\n", signo); }int main() {int ret;struct sigaction act;act.sa_handler = docatch;sigemptyset(&act.sa_mask);sigaddset(&act.sa_mask, SIGQUIT);act.sa_flags = 0; //默認屬性:信號捕捉函數執行期間,自動屏蔽本信號ret = sigaction(SIGINT, &act, NULL);if(ret < 0) {perror("sigaction error");exit(1);}while(1)sleep(1);return 0; }輸出結果:
?
信號捕捉特性:
- 進程正常運行時,默認PCB有一個信號屏蔽字,假定為☆,它決定了進程自動屏蔽哪些信號,當注冊了某個信號步捕捉函數,捕捉到該信號以后,要調用該函數,而該函數有可能執行很長時間,在這期間所屏蔽的信號不由☆指定,而由sa_mask來指定,調用完信號處理函數,再恢復為☆。
- xxx信號捕捉函數執行期間,XXX信號自動屏蔽。
- 阻塞的常規信號不支持排隊,產生多次只記錄一次(后32個實時信號支持排隊)
?
?
2. 測試代碼:
#include <stdio.h> #include <signal.h> #include <stdlib.h> #include <unistd.h>void docatch(int signo) {printf("%d signal is catch\n", signo);sleep(10);printf("--------------finish\n"); }int main() {int ret;struct sigaction act;act.sa_handler = docatch;sigemptyset(&act.sa_mask);sigaddset(&act.sa_mask, SIGQUIT);act.sa_flags = 0;ret = sigaction(SIGINT, &act, NULL);if (ret < 0) {perror("sigaction error");exit(1);}while (1) sleep(1);return 0; }輸出結果:
?
#include <sys/wait.h> #include <signal.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h>void sys_err(char *str) {perror(str);exit(1); }void do_sig_child(int signo) {int status;pid_t pid;while ((pid = waitpid(0, &status, WNOHANG)) > 0) {if (WIFEXITED(status))printf("---------------------------child %d exit %d\n", pid, WEXITSTATUS(status));else if (WIFSIGNALED(status))printf("child %d cancel signal %d\n", pid, WTERMSIG(status));} }int main() {pid_t pid;int i;for (i = 0; i < 10; i++) {if ((pid = fork()) == 0)break;else if (pid < 0)sys_err("fork");}if (pid == 0) //子進程{int n = 1;while (n--) {printf("child ID %d\n", getpid());sleep(1);}return i + 1;}else if (pid > 0) //父進程{struct sigaction act; //SIGCHLD阻塞act.sa_handler = do_sig_child;sigemptyset(&act.sa_mask);act.sa_flags = 0;sigaction(SIGCHLD, &act, NULL); //解除對SIGCHLD的阻塞 while (1) {printf("parent ID %d\n", getpid());sleep(1);}}return 0; }?
總結
以上是生活随笔為你收集整理的函数signal、sigaction的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【信号】信号集、sigprocmask、
- 下一篇: 信号 09 | 函数pause