信号集的初始操作
信号集 : 能够表示多个信号的数据类型
#include <signal.h>// 以下函数, 成功, 返回 0; 失败, 返回 -1.int sigemptyset(sigset_t *set) // 清除信号集中的所以信号int sigfillset(sigset_t *set) // 初始化set信号集中的信号, 并把所有该程序的信号加入到信号集中int sigaddset(sigset_t *set, int signo) // 添加signo信号到信号集中int sigdelset(sigset_t *set, int signo) // 信号集中删除signo信号// 成功,返回 1; 失败, 返回 0.int sigismember(const sigset_t *set, int signo) // 测试一个指定的位
在所有应用程序使用信号集之前, 要对信号集调用sigemptyset和sigfillset一次.
sigprocmask 函数
#include <signal.h>int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oset)// 成功, 返回 0; 失败, 返回 -1.
关于sigpromask()函数的各个参数的取值对函数功能的影响很重要, 这个函数也是signal信号集很重要的一部分.
how可设置的参数为:SIG_BLOCK, SIG_UNBLOCK,SIG_SETMASK
SIG_BLOCK :按照参数 set 提供的屏蔽字,屏蔽信号。并将原信号屏蔽保存到oldset中。
SIG_UNBLOCK :按照参数 set 提供的屏蔽字进行信号的解除屏蔽。针对set中的信号进行解屏。
SIG_SETMASK : 按照参数 set 提供的信号设置重新设置系统信号。即, 该进程新的屏蔽字是 set 的值。
关于常见的sigprocmask()函数的操作
- sigprocmask(SIG_BLOCK, set, NULL)
- 屏蔽set中保存的信号
- 可更新程序的信号集
- sigprocmask(SIG_UNBLOCK, set, NULL)
- 当前的程序中set中包含的信号全部取消屏蔽
- sigprocmask(SIG_SETMASK, set, NULL)
- 程序的屏蔽字为set信号集中包含的信号
- 可更新程序的信号集
/*************************************************************************> File Name: t.cpp> Author: Function_Dou> Mail:> Created Time: 2018年02月03日 星期六 17时58分22秒************************************************************************/#include <stdio.h>#include <signal.h>#include "apue.h"void checkset(int i);int main(){sigset_t blockset;sigemptyset(&blockset);// 添加两个信号进入信号集中sigaddset(&blockset,SIGINT);sigaddset(&blockset,SIGTSTP);// 测试信号集中由SIGINT信号了if(sigismember(&blockset,SIGINT))printf("SIGINT\n\n");// 没有信号输出是因为当前的信号集还是NULL(空的)checkset(0);// 将blockset信号集变为当前程序的信号集sigprocmask(SIG_SETMASK, &blockset,NULL);if(sigismember(&blockset,SIGINT))printf("SIGINT\n\n");// 现在的信号集不再为NULL了.checkset(1);sigaddset(&blockset,SIGTERM);// sigprocmask(SIG_SETMASK, &blockset,NULL);// 此时的SIG_BLOCK意义跟SIG_SETMASK意义一样, 都是更新当前blockset信号集:sigprocmask(SIG_BLOCK,&blockset,NULL);checkset(2);// SIG_UNBLOCK 将blockset 信号集全部取消屏蔽. 也就是程序取消了对信号集的屏蔽了, 但是blockset中的信号还是存在的.sigprocmask(SIG_UNBLOCK,&blockset,NULL);if(sigismember(&blockset,SIGTERM))printf("SIGTERM\n");if(sigismember(&blockset,SIGINT))printf("SIGINT\n");if(sigismember(&blockset,SIGTSTP))printf("SIGSTP\n\n");// 检测到程序中的信号屏蔽已经没有了.checkset(3);if(sigismember(&blockset,SIGTERM))printf("SIGTERM\n");if(sigismember(&blockset,SIGINT))printf("SIGINT\n");if(sigismember(&blockset,SIGTSTP))printf("SIGTSTP\n");checkset(4);}void checkset(int i){sigset_t set;printf("check set start:%d\n", i);if(sigprocmask(SIG_SETMASK, NULL, &set) < -1){printf("check set sig procmask error!!\n");exit(0);}if(sigismember(&set,SIGINT))printf("SIGINT\n");if(sigismember(&set,SIGTSTP))printf("SIGTSTP\n");if(sigismember(&set,SIGTERM))printf("SIGTERM\n");printf("check set end\n\n");}
运行结果
[root@localhost Signal]# ./a.outSIGINTcheck set start:0check set endSIGINTcheck set start:1SIGINTSIGTSTPcheck set endcheck set start:2SIGINTSIGTSTPSIGTERMcheck set endSIGTERMSIGINTSIGSTPcheck set start:3check set endSIGTERMSIGINTSIGTSTPcheck set start:4check set end
关于sigprocmask()函数理解, 在此我还写了一个更简单的程序, 方便理解程序中的屏蔽信号
/*************************************************************************> File Name: z.cpp> Author: Function_Dou> Mail:> Created Time: 2018年02月03日 星期六 22时55分58秒************************************************************************/#include <stdio.h>#include <stdlib.h>#include <signal.h>static void Fun(sigset_t sigset){if(sigismember(&sigset, SIGSEGV))printf("SIGEGV\n");if(sigismember(&sigset, SIGINT))printf("SIGINT\n");if(sigismember(&sigset, SIGTERM))printf("SIGTERM\n");if(sigismember(&sigset, SIGALRM))printf("SIGALRM\n");}int main(){sigset_t new_sigset, old_sigset;sigemptyset(&new_sigset);sigemptyset(&old_sigset);sigaddset(&new_sigset, SIGSEGV);sigaddset(&new_sigset, SIGINT);sigaddset(&new_sigset, SIGTERM);printf("1 new_sigset\n");Fun(new_sigset);printf("\n\n");sigprocmask(SIG_BLOCK, &new_sigset, &old_sigset);printf("2 old_sigset\n");Fun(old_sigset);printf("\n\n");printf("3 new_sigset\n");Fun(new_sigset);printf("\n\n");// sigaddset(&old_sigset, SIGALRM);sigaddset(&new_sigset, SIGALRM);sigprocmask(SIG_BLOCK, &new_sigset, &old_sigset);printf("4 old_sigset\n");Fun(old_sigset);printf("\n\n");printf("5 new_sigset\n");Fun(new_sigset);printf("\n\n");// 取消new_sigset中的信号屏蔽, 此时程序的信号集为NULLsigprocmask(SIG_UNBLOCK, &new_sigset, &old_sigset);printf("6 old_sigset\n");Fun(old_sigset);printf("\n\n");printf("7 new_sigset\n");Fun(new_sigset);printf("\n\n");// 这里old_sigset信号集中的信号为NULL, 因为上次程序的屏蔽字为NULLsigprocmask(SIG_SETMASK, &new_sigset, &old_sigset);printf("8 old_sigset\n");Fun(old_sigset);printf("\n\n");printf("9 new_sigset\n");Fun(new_sigset);printf("\n\n");exit(0);}
运行结果
[root@localhost Signal]# ./a.out1 new_sigsetSIGEGVSIGINTSIGTERM2 old_sigset3 new_sigsetSIGEGVSIGINTSIGTERM4 old_sigsetSIGEGVSIGINTSIGTERM5 new_sigsetSIGEGVSIGINTSIGTERMSIGALRM6 old_sigsetSIGEGVSIGINTSIGTERMSIGALRM7 new_sigsetSIGEGVSIGINTSIGTERMSIGALRM8 old_sigset9 new_sigsetSIGEGVSIGINTSIGTERMSIGALRM
写了这么多的代码, 就是为了方便理解sigprocmask()函数各个参数的意义, 以及基础的运用.
希望对你有所帮助!

本文深入讲解了信号处理函数sigprocmask的使用方法及其参数如何影响函数的功能。通过实例演示了如何利用sigemptyset、sigfillset等函数操作信号集,并展示了如何通过sigprocmask函数实现信号的屏蔽、解除屏蔽及更新程序信号集。
526

被折叠的 条评论
为什么被折叠?



