Linux c 屏蔽信号、切换信号
信号导致的问题
不是任何信号我们都需要的,如果遇到我们不想处理的信号,我们怎么避免这个信号?
1. 信号屏蔽
intsigprocmask(int how,//操作方式
SIG_BLOCK屏蔽信号
SIG_UNBLOCK剪除屏蔽信号
SIG_SETMASK修改屏蔽信号
constsigset_t *sigs,//操作的信号集合
sigset_t*oldsigs);//返回原来操作的信号集合
返回值:执行成功返回0,失败返回-1。
屏蔽信号的步骤:
1. 声明信号集
sigset_t sigs;
2. 加入屏蔽信号
一组信号集合维护函数
2.1. 清空集合sigemptyset
int sigemptyset( sigset_t *set);
2.2. 添加信号到集合sigaddset
int sigaddset( sigset_t *set ,int signum);
2.3. 从集合删除信号sigdelset
int sigdelset(sigset_t *set,int signum);
2.4. 添加所有信号到集合sigfillset
int sigfillset( sigset_t*set);
2.5. 判定信号是否在集合sigismember
int sigismember(const sigset_t *set ,int signum);
3. 屏蔽信号
4. 接触屏蔽
例子:
#include<stdio.h>
#include<signal.h>
void main()
{
int sum=0;
//声明信号集
sigset_t sigs;
//清空信号集
sigemptyset(&sigs);
//添加信号到信号集
sigaddset(&sigs,SIGINT); //
//屏蔽信号
sigprocmask( SIG_BLOCK,&sigs,0);
for(i=1;i<=10;i++)
{
sum+=i;
sleep(1);
}
printf(“sum=%d\n”,sum);
//捡出屏蔽
sigprocmask(SIG_UNBLOCK,&sigs,0);//捡出屏蔽,信号立即触犯,打印over不能//执行,如果没有捡出屏蔽信号,over正常打印
printf(“OVER!\n”);
}
说明:当屏蔽了某个信号,这个信号将不会触发,直到我们捡出了该信号,信号才会触发。
2.查询被屏蔽的信号
intsigpending(sigset_t *sets); 返回0成功,-1失败
例子:
#include<stdio.h>
#include<signal.h>
void main()
{
int sum=0;
//声明信号集
sigset_t sigs;
sigset_t sigp;
//清空信号集
sigemptyset(&sigs);
//添加信号到信号集
sigaddset(&sigs,SIGINT); //
//屏蔽信号
sigprocmask( SIG_BLOCK,&sigs,0);
for(i=1;i<=10;i++)
{
sum+=i;
sigpending(&sigp);//得到屏蔽的信号
if(sigismemeber(&sigp,SIGINT))
{
printf(“信号SIGINT在排队\n”);
}
sleep(1);
}
printf(“sum=%d\n”,sum);
//捡出屏蔽
sigprocmask(SIG_UNBLOCK,&sigs,0);
printf(“OVER!\n”);
}
2. 信号屏蔽的切换
int sigsuspend(sigset_t *sigs);
屏蔽新的信号,原来的信号失效.
sigsuspend是阻塞函数.对参数信号屏蔽.
对参数没有指定的信号不屏蔽,但当没有屏蔽信号处理函数调用完毕
sigsuspend返回条件:
1.信号发生,并且信号是非屏蔽信号
2.信号必须要处理,而且处理函数返回后,sigsuspend才返回.
sigsuspend设置新的屏蔽信号,保存旧的屏蔽信号
而且当sigsuspend返回的时候,恢复旧的屏蔽信号.
函数sigsuspend将进程的信号屏蔽码设置为sigs,然后与pause()函数一样等待信号的发生并执行完信号处理函数。信号处理函数执行完后再把进程的信号屏蔽码设置为原来的屏蔽字,然后sigsuspend函数才返回。 Sigsuspend总是返回-1。
例子:
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
void deal()
{
printf(“处理信号SIGINT\n”);
}
void main()
{
signal(SIGINT,deal);
int sum=0;
//声明信号集
sigset_t sigs;
sigset_t sigp;
sigset_t newsig=NULL;
//清空信号集
sigemptyset(&sigs);
//添加信号到信号集
sigaddset(&sigs,SIGINT); //
//屏蔽信号
sigprocmask( SIG_BLOCK,&sigs,0);
for(i=1;i<=10;i++)
{
sum+=i;
sigpending(&sigp);//得到屏蔽的信号
if(sigismemeber(&sigp,SIGINT))
{
printf(“信号SIGINT在排队\n”);
sigsuspend(&newsig);//切换屏蔽信号,等待SIGINT信号,并调用处//理函数后函数返回。
}
sleep(1);
}
printf(“sum=%d\n”,sum);
}
说明:程序检查到屏蔽信号中有SIGINT信号在排队,就调用sigsuspend函数切换屏蔽信号,程序处理SIGINT信号后,sigsuspend函数才返回。
Linux c 屏蔽信号、切换信号的更多相关文章
- Linux信号-信号集&信号屏蔽字&捕捉信号【转】
转自:https://blog.csdn.net/Lycorisradiata__/article/details/80096203 一. 阻塞信号 1. 信号的常见其他概念 实际执行信号的处理 ...
- 三十四、Linux 进程与信号——信号特点、信号集和信号屏蔽函数
34.1 信号特点 信号的发生是随机的,但信号在何种条件下发生是可预测的 进程杠开始启动时,所有信号的处理方式要么默认,要么忽略:忽略是 SIGUSR1 和 SIGUSR2 两个信号,其他都采取默认方 ...
- 信号屏蔽的切换的理解sigsuspend
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h&g ...
- Linux C 程序 信号及信号的处理(19)
信号及信号的处理 1.Linux信号的介绍 信号是一种软件中断.Linux系统中根据POSIX标准扩展的信号机制. 1.信号来源 1.硬件方式 1.当用户按下某个键, ...
- Linux系统编程之----》信号
"===信号========================================================================================= ...
- Linux系统编程——进程间通信:信号中断处理
什么是信号? 信号是 Linux 进程间通信的最古老的方式.信号是url=474nN303T2Oe2ehYZjkrggeXCaJPDSrmM5Unoh4TTuty4wSgS0nl4-vl43AGMFb ...
- Linux下shell脚本中信号捕获和函数练习脚本之ping一个网段
该脚本主要的目的是练习在Linux bash脚本中捕获信号,顺便练习一下函数的使用,还有就是终止一个正在运行的程序后,该程序打开的文件的后续处理问题等等!脚本功能: ping一个网段内的IP,检测哪 ...
- [Linux]返回被阻塞的信号集
一.概述 在另一篇实例说到,进程可以屏蔽它不想接收的信号集. 事实上这些被屏蔽的信号只是阻塞在内核的进程表中,因为他们不能递送给进程,所以状态是未决的(pending). 利用sigpending函数 ...
- linux 进程学习笔记-进程信号sigal
信号(或软中断)是在软件层次上对中断的一个模拟,其运行在“用户空间”,一个进程对另外一个或几个进程通过发送信号来实现异步通信.当接收进程接收到信号后,其可以注册一下处理函数来说对这些信号进行处理(也可 ...
随机推荐
- 「WC2016」挑战NPC
「WC2016」挑战NPC 解题思路 这个题建图非常厉害,带花树什么的只会口胡根本写不动,所以我写了机房某大佬教我的乱搞. 考虑把一个筐 \(x\) 拆成 \(x1,x2,x3\) 三个点,且这三个点 ...
- luoguP2490 [SDOI2011]黑白棋 博弈论 + 动态规划
博弈部分是自己想出来的,\(dp\)的部分最后出了点差错QAQ 从简单的情况入手 比如\(k = 2\) 如果有这样的局面:$\circ \bullet $,那么先手必输,因为不论先手怎样移动,对手都 ...
- BZOJ 4826: [Hnoi2017]影魔 单调栈 主席树
https://www.lydsy.com/JudgeOnline/problem.php?id=4826 年少不知空间贵,相顾mle空流泪. 和上一道主席树求的东西差不多,求两种对 1. max(a ...
- POJ2104 K-th Number 不带修改的主席树 线段树
http://poj.org/problem?id=2104 给定一个序列,求区间第k小 通过构建可持久化的点,得到线段树左儿子和右儿子的前缀和(前缀是这个序列从左到右意义上的),然后是一个二分的ge ...
- [COGS2479]偏序
[COGS2479]偏序 题目大意: \(n(n\le50000)\)个四元组,求四维偏序. 思路: CDQ分治套CDQ分治套树状数组. 细节: 第二层CDQ之前要备份数组\(a\),否则第二层CDQ ...
- hdu 4118 dfs
题意:给n个点,每个点有一个人,有n-1条有权值的边,求所有人不在原来位置所移动的距离的和最大值.不能重复 这题的方法很有看点啊,标记为巩固题 Sample Input 1 4 1 2 3 2 3 2 ...
- hdu 1208 记忆化搜索
题目大意:只能按照格子上的数字*方向走,从左上走到右下Sample Input42331121312313110Sample Output3 直接记忆化搜索,注意是0的情况 #include<c ...
- python日常碎碎念
关于取命令行中参数的方法 1,sys.argv 这个方法自动获取参数,并split.一般情况下第一个元素是程序的名字.即 python script.py arg1 arg2 然后sys.argv返回 ...
- leetcode660. Remove 9
leetcode660. Remove 9 题意: 从整数1开始,删除任何包含9的整数,如9,19,29 ... 所以现在,你将有一个新的整数序列:1,2,3,4,5,6,7,8,10,11,... ...
- JavaEE-学习目录
JavaEE ============================================ Web工作机制 JSP Struts基础 Struts核心文件 Struts数据校验与国际化 S ...