信号集的初始操作
信号集 : 能够表示多个信号的数据类型
#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.out
SIGINT
check set start:0
check set end
SIGINT
check set start:1
SIGINT
SIGTSTP
check set end
check set start:2
SIGINT
SIGTSTP
SIGTERM
check set end
SIGTERM
SIGINT
SIGSTP
check set start:3
check set end
SIGTERM
SIGINT
SIGTSTP
check set start:4
check 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中的信号屏蔽, 此时程序的信号集为NULL
sigprocmask(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, 因为上次程序的屏蔽字为NULL
sigprocmask(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.out
1 new_sigset
SIGEGV
SIGINT
SIGTERM
2 old_sigset
3 new_sigset
SIGEGV
SIGINT
SIGTERM
4 old_sigset
SIGEGV
SIGINT
SIGTERM
5 new_sigset
SIGEGV
SIGINT
SIGTERM
SIGALRM
6 old_sigset
SIGEGV
SIGINT
SIGTERM
SIGALRM
7 new_sigset
SIGEGV
SIGINT
SIGTERM
SIGALRM
8 old_sigset
9 new_sigset
SIGEGV
SIGINT
SIGTERM
SIGALRM
写了这么多的代码, 就是为了方便理解sigprocmask()函数各个参数的意义, 以及基础的运用.
希望对你有所帮助!