信号集的函数:

类型:sigset_t 类型

/****************************
*功能:把一个信号集的内容清空
*参数:sigset_t *set:是一个信号集,sigset_t的类型一定是可以容纳所有的信号的个数
*返回值:成功返回0,失败返回-1
* ************************/
int sigemptyset(sigset_t *set);

/****************************
*功能:把一个信号集的内容填满,包含所有的信号
*参数:sigset_t *set:是一个信号集,sigset_t的类型一定是可以容纳所有的信号的个数
*返回值:成功返回0,失败返回-1
* ************************/
int sigfillset(sigset_t *set);


/****************************
*功能:把一个信号添加到信号集中
*参数:sigset_t *set:是一个信号集,sigset_t的类型一定是可以容纳所有的信号的个数
*返回值:成功返回0,失败返回-1
* ************************/
int sigaddset(sigset_t *set, int signum);

/****************************
*功能:把一个信号从信号集中删除
*参数:sigset_t *set:是一个信号集,sigset_t的类型一定是可以容纳所有的信号的个数
*返回值:成功返回0,失败返回-1
* ************************/
int sigdelset(sigset_t *set, int signum);

/****************************
*功能:判断是否是信号是否在指定集合中
*参数:sigset_t *set:是一个信号集,sigset_t的类型一定是可以容纳所有的信号的个数
*返回值:成功返回0,失败返回-1
* ************************/
int sigismember(const sigset_t *set, int signum);

sigprocmask函数:

用来读取或者更改进程的信号屏蔽集。

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

如果 set 为空 oldset 不为空, 则会将进程原来的信号屏蔽集传出;
如果 set 不为空,oldset 为空, 则会根据 how 参数的指示修改进程的信号屏蔽集;
如果两个指针都不为空, 则先备份原来的信号屏蔽字到 oldset, 然后根据 how参数修改。

how参数有如下函数


含义

SIG_BLOCK

屏蔽信号,添加的信号屏蔽字不覆盖之前的,这是一个并集的关系 

SIG_UNBLOCK

希望解除BLOCK的信号集合。

SIG_SETMASK

该进程的信号屏蔽是set指向的值。

注意到这里后两个参数,​​set​​​用以设置新的信号屏蔽字,​​oldset​​返回当前信号屏蔽字。

如果不进行设置,仅仅只是想得到当前的信号屏蔽字,那么前两个参数也就没有意义了。

sigprocmask(0,NULL,&sigset);

sigpending函数:

int sigpending(sigset_t *set);

函数说明:sigpending()会将被阻塞的信号集合由参数set 指针返回.

返回值:执行成功则返回 0, 如果有错误则返回-1.

 

简单程序实例:

程序运行时,每秒打印一此未决状态信号集,初始全为0,当输出ctrl-c时, 由于我们阻塞了SIGINT信号, 会使该信号处于未决状态。

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <pwd.h>
#include <signal.h>

// 打印信号集
void
printsigset(const sigset_t *set)
{
int i = 0;
for(; i<6; ++i)
{
if(sigismember(set, i) == 1)
printf("signal[%d] = 阻塞\n", i);
else
printf("signal[%d] = 未阻塞\n", i);
}
printf("\n");
}

int
main()
{
sigset_t s;
sigemptyset(&s); // 初始化
sigaddset(&s, SIGINT); //添加SIGINT,
sigprocmask(SIG_BLOCK, &s, NULL ); //把当前信号集 s 变为 屏蔽信号集,
//这个信号集里的信号会被阻塞
while(1)
{
sigpending(&s);
printsigset(&s);
sleep(3);
}

return 0;
}

结果:

Linux信号集_阻塞状态

Linux信号集_阻塞状态_02

 

 

该程序的运行结果如下, 可以看见, 在信号处于阻塞状态时, 所发出的信号对进程不起

作用, 并且该信号进入待处理状态。 读者按任意键, 并且信号脱离了阻塞状态后, 用户发出
的信号才能正常运行。 这里 SIGINT 已按照用户自定义的函数运行, 请读者注意阻塞状态下
SIGINT 的处理和非阻塞状态下 SIGINT 的处理有何不同。

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <pwd.h>
#include <signal.h>

/* 自定义的信号处理函数 */
void my_func(int signum)
{
printf("If you want to quit,please try SIGQUIT\n");
}
int main()
{
sigset_t set;
sigset_t pendset;
struct sigaction action1;
struct sigaction action2;
/* 初始化信号集为空 */
if (sigemptyset(&set) < 0)
{
perror("sigemptyset");
exit(1);
} /* 将相应的信号加入信号集 */

if (sigaddset(&set, SIGQUIT) < 0)
{
perror("sigaddset");
exit(1);
}

if (sigaddset(&set, SIGINT) < 0)
{
perror("sigaddset");
exit(1);
}

if (sigismember(&set, SIGINT))
{
sigemptyset(&action1.sa_mask);
action1.sa_handler = my_func;
action1.sa_flags = 0;
sigaction(SIGINT, &action1, NULL); //注册函数
}
if (sigismember(&set, SIGQUIT))
{
sigemptyset(&action2.sa_mask);
action2.sa_handler = SIG_DFL;
action2.sa_flags = 0;
sigaction(SIGQUIT, &action2,NULL); //注册函数
}
/* 设置信号集屏蔽字, 此时 set 中的信号不会被传递给进程, 暂时进入待处理状态 */

if (sigprocmask(SIG_BLOCK, &set, NULL) < 0)
{
perror("sigprocmask");
exit(1);
}else
{
printf("Signal set was blocked, Press any key!");
//getchar(); /*按下键后就会执行信号函数*/
}
/* 在信号屏蔽字中删除 set 中的信号 */
if (sigprocmask(SIG_UNBLOCK, &set, NULL) < 0)
{
perror("sigprocmask");
exit(1);
}else
{
printf("Signal set is in unblock state\n");
}
while(1);
exit(0);
}

结果:

# ./a.out 
Signal set was blocked, Press any key!^C^C^C    //按下多次ctr+c,但只处理一次
If you want to quit,please try SIGQUIT
Signal set is in unblock state                                /* 从信号屏蔽字中删除 set 中的信号 */
^CIf you want to quit,please try SIGQUIT           /* 非阻塞状态下 SIGINT 的处理 */
^CIf you want to quit,please try SIGQUIT