函数函数sigaction、signal
生活随笔
收集整理的這篇文章主要介紹了
函数函数sigaction、signal
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
函數(shù)函數(shù)sigaction
1. 函數(shù)sigaction原型:
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);分析:
- 參數(shù) signum :要捕獲的信號。
- 參數(shù)act:truct sigaction 結(jié)構(gòu)體,后面具體講解傳入?yún)?shù),新的處理方式
- 參數(shù)oldact:返回舊的 struct sigaction 結(jié)構(gòu)體,傳出參數(shù),舊的處理方式
?
1.2?struct sigaction 結(jié)構(gòu)體
1 struct sigaction 2 { 3 void(*sa_handler)(int); 4 void(*sa_sigaction)(int, siginfo_t *, void *); 5 sigset_t sa_mask; 6 int sa_flags; 7 void(*sa_restorer)(void); 8 };分析:
- sa_handler : 不帶附加參數(shù)的信號處理函數(shù)指針
- sa_sigaction: 帶有附加參數(shù)的信號處理函數(shù)指針(兩個(gè)信號處理函數(shù)指針只能二選一)
- sa_mask: 在執(zhí)行信號處理函數(shù)時(shí),應(yīng)該屏蔽掉哪些信號
- sa_flags: 用于控制信號行為,它的值可以是下面選項(xiàng)的組合。
- SA_SIGINFO:如果指定該選項(xiàng),則向信號處理函數(shù)傳遞參數(shù)(這時(shí)應(yīng)該使用 sa_sigaction 成員而不是 sa_handler).
- sa_restorer:該成員在早期是用來清理函數(shù)棧的,如今已被廢棄不用。
注意:sa_flags 的選項(xiàng)比較多,大部分可又自己做實(shí)驗(yàn)驗(yàn)證,有些是需要額外的知識,比如 SA_ONESTACK 和 SA_RESTART,這些放到后面講解。本節(jié)示例中,只需要把 sa_flags 設(shè)置為 0 即可。
?
信號捕捉特性:
- 進(jìn)程正常運(yùn)行時(shí),默認(rèn)PCB有一個(gè)信號屏蔽字,假定為☆,它決定了進(jìn)程自動(dòng)屏蔽哪些信號,當(dāng)注冊了某個(gè)信號步捕捉函數(shù),捕捉到該信號以后,要調(diào)用該函數(shù),而該函數(shù)有可能執(zhí)行很長時(shí)間,在這期間所屏蔽的信號不由☆指定,而由sa_mask來指定,調(diào)用完信號處理函數(shù),再恢復(fù)為☆。
- xxx信號捕捉函數(shù)執(zhí)行期間,XXX信號自動(dòng)屏蔽。
- 阻塞的常規(guī)信號不支持排隊(duì),產(chǎn)生多次只記錄一次(后32個(gè)實(shí)時(shí)信號支持排隊(duì))
?
1. 測試代碼:
1 #include<stdio.h> 2 #include<signal.h> 3 #include<stdlib.h> 4 #include<unistd.h> 5 6 void docatch(int signo) 7 { 8 printf("%d signal is catch\n", signo); 9 } 10 11 int main() 12 { 13 int ret; 14 struct sigaction act; 15 act.sa_handler = docatch; 16 sigemptyset(&act.sa_mask); 17 sigaddset(&act.sa_mask, SIGQUIT); 18 act.sa_flags = 0; //默認(rèn)屬性:信號捕捉函數(shù)執(zhí)行期間,自動(dòng)屏蔽本信號 19 ret = sigaction(SIGINT, &act, NULL); 20 if(ret < 0) 21 { 22 perror("sigaction error"); 23 exit(1); 24 } 25 while(1) 26 sleep(1); 27 return 0; 28 }輸出結(jié)果:
?
?2. 測試代碼:
1 #include<stdio.h> 2 #include<signal.h> 3 #include<stdlib.h> 4 #include<unistd.h> 5 6 void docatch(int signo) 7 { 8 printf("%d signal is catch\n", signo); 9 sleep(10); 10 printf("--------------finish-\n"); 11 } 12 13 int main() 14 { 15 int ret; 16 struct sigaction act; 17 act.sa_handler = docatch; 18 sigemptyset(&act.sa_mask); 19 sigaddset(&act.sa_mask, SIGQUIT); 20 act.sa_flags = 0; 21 ret = sigaction(SIGINT, &act, NULL); 22 if (ret < 0) 23 { 24 perror("sigaction error"); 25 exit(1); 26 } 27 while (1) 28 sleep(1); 29 return 0; 30 }輸出結(jié)果:
?
3. 測試代碼:
1 #include <unistd.h> 2 #include <signal.h> 3 #include <stdio.h> 4 5 void printsigset(const sigset_t *set) 6 { 7 for (int i = 1; i <= 64; i++) 8 { 9 if (i == 33) putchar(' '); 10 if (sigismember(set, i) == 1) 11 putchar('1'); 12 else 13 putchar('0'); 14 } 15 puts(""); 16 } 17 18 void handler(int sig) 19 { 20 if (sig == SIGTSTP) 21 printf("hello SIGTSTP\n"); 22 if (sig == SIGINT) 23 printf("hello SIGINT\n"); 24 sleep(5); 25 sigset_t st; 26 sigpending(&st); 27 printsigset(&st); 28 } 29 30 int main() 31 { 32 printf("I'm %d\n", getpid()); 33 struct sigaction act, oldact; 34 act.sa_handler = handler; // 設(shè)置普通信號處理函數(shù) 35 sigemptyset(&act.sa_mask); // 向 sa_mask 中添加 SIGINT 36 sigaddset(&act.sa_mask, SIGINT); 37 act.sa_flags = 0; // 先置 0 38 39 sigaction(SIGTSTP, &act, &oldact); 40 sigaction(SIGINT, &act, &oldact); 41 42 while (1) 43 { 44 write(STDOUT_FILENO, ".", 1); 45 pause(); 46 } 47 return 0; 48 }輸出結(jié)果:
分析:
- 當(dāng)程序運(yùn)行的時(shí)候,Ctrl C 進(jìn)入 handler,然后立即 Ctrl Z 發(fā)現(xiàn) handler 還未執(zhí)行完就被 SIGTSTP 打斷.
- 當(dāng)程序運(yùn)行的時(shí)候,Ctrl Z 進(jìn)入 handler,然后立即 Ctrl C 發(fā)現(xiàn)并不會(huì)被 SIGINT 打斷,這是因?yàn)樵?handler 注冊的時(shí)候被設(shè)置了 SA_MASK = SIGINT。最后 handler 結(jié)束的時(shí)候打印了未決信號集,發(fā)現(xiàn)里頭有 SIGINT。所以 handler 結(jié)束后,又去繼續(xù)對 SIGINT 進(jìn)行處理。
?
轉(zhuǎn)載于:https://www.cnblogs.com/sunbines/p/10265659.html
總結(jié)
以上是生活随笔為你收集整理的函数函数sigaction、signal的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 博客园使用latex编辑公式
- 下一篇: javaweb学习6——自定义标签