开发者学堂课程【物联网开发- Linux 高级程序设计全套视频:Sigprocmask 函数】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/660/detail/11024
Sigprocmask 函数
内容介绍
一、Sigprocmask 函数概述
二、讲解阻塞集合
三、举例演示
一、Sigprocmask 函数概述
创建一个阻塞集合
#include <signal.h>
int sigprocmask(int how, const sigset t *set, sigset_t *oldset);
How 对这个阻塞集合进行什么样的操作,set集合的地址,对阻塞集合操作的集合,oldset 是保存原来的阻塞集合。
保存的目的是为了保证阻塞集合变的时候,可以将原来的阻塞集合备份。
功能:
检查或修改信号阻塞集,根据 how 指定的方法对进程的阻塞集合进行修改,新的信号阻塞集由 set 指定,i而原先的信号阻塞集合由 oldset 保存。
参数:
how:信号阻塞集合的修改方法。
set:要操作的信号集地址。
oldset:保存原先信号集地址。
how:
SIG BLOCK:向信号阻塞集合中添加set信号集
SIG UNBLOCK:从信号阻塞集合中删除sct集合
SIG SETMASK:将信号阻寨集合设为set集合
二、讲解阻塞集合
假如说初始化一个空集合
sigset_ t set1;
sigemptset(&set1);
sigaddset(&set1,2);
sigaddset(&set1,3);
set1 这个集合当中有两个信号了
Sigset_t oldset
定义一个集合是 oldset,将来保存以前的信号集合
1、定义一个 set1
sigprocmask(SIG BLOCK,&sell,&oldset);
这样调用的结果假如说默认有一个阻塞集合,这样的意思是将set1这个集合添加到集合里面去,集合中的2号信号和3号信号就到了阻塞集合里面去了,
如图
2号信号和3号信号在当前进程当中就被屏蔽了,屏蔽之后再次发送2号信号和三号信号是收不到的,还有一点需要注意,
如果说将set1添加到阻塞集合之前已经有2号信号了,将 set1 添加进来之后,这个集合仍然还有一个2号信号,集合当中的信号是不能重复的。
假如说添加之前阻塞集合里面的信号是2,6,8,然后我们调用代码,将 set1 集合的2,3调用到阻塞集合里面,那么阻塞集合里面就多了一个3,但是在多3之前,需要注意第三个参数是oldset集合,所以他会先将阻塞集合备份到oldset当中去。
2、定义一个set2
sigaddset(&set2,2);
sigaddset(&set2,6);
set2集合中含有信号2,6
sigprocmask(SIG UNBLOCK,&set2,&oldset);
SIG UNBLOCK将set2集合当中的2和6踢出去
3、定义一个set3
siqaddset(&set3,2);
sigaddset(&set3,5);
sigaddset(&set3,8);
set3中含有信号2,5,8
sigprocmask(SIG SETMASK&set3,&oldset);
调这句话的作用是将阻塞集设为set3的信号,其他的都不要了
总体来说,这个函数有三种用法,第一种是将集合里面的信号放到阻塞集合里面去,第二种是将集合里面的信号从阻塞集合中踢出去,第三种是直接将阻塞集合里面的信号设置成set3集合里面的信号。
sigprocmask(SIG BLOCK,&sell,&oldset);
sigprocmask(SIG UNBLOCK,&set2,&oldset);
sigprocmask(SIG SETMASK&set3,&oldset);
注:
着set为NULL,则下改变信号阻塞集合,函数只把当前信号阻塞集合保存到 oldset 中。
返回值:
成功:返回 0失败:返回 -1
三、举例演示
这个举例说的是初始化一个集合,然后将集合添加到阻塞集里面去,所以集合当中的信号就被屏蔽了,那个时候发信号就是接收不到的,解除阻塞发信号就可以接收到
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
int main(int arge, char *argv[])
{
Sigset_t set ;
int i=0; 1
sigemptyset(&set);
sigaddsel(&sel,SIGINT);
while(1)
{
sigprocmask(SIG BLOCK,&set,NULL);
for(i=0;i<5;i++)
{
printf("STGTNT signal is blocked\n");
sleep(1);
}
for循环每五秒打印一条提示信息,在这循环五秒的时候按 Ctrl+C 是不好用的,他不接收二号信号,如果在这五秒内没有按过 Ctrl+C
sigprocmask(SIG UNBLOCK,&setNULL);
五秒钟是接触阻塞了,那么在这循环里面就是能接收到的
for(i=0; i<5; i++)
{
printf("SIGINT signal unblocked\n");
sleep(1);
}
}
return 0;
这个程序验证了,如果某一个信号在阻塞集合里面,给他发送信号是不好用的,一旦解除阻塞,马上就可以给他发送信号了,如果以前发过,那马上就能收到,如果没发过,就可以发送了。