信号导致的问题

不是任何信号我们都需要的,如果遇到我们不想处理的信号,我们怎么避免这个信号?

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 屏蔽信号、切换信号的更多相关文章

  1. Linux信号-信号集&信号屏蔽字&捕捉信号【转】

    转自:https://blog.csdn.net/Lycorisradiata__/article/details/80096203 一. 阻塞信号 1. 信号的常见其他概念    实际执行信号的处理 ...

  2. 三十四、Linux 进程与信号——信号特点、信号集和信号屏蔽函数

    34.1 信号特点 信号的发生是随机的,但信号在何种条件下发生是可预测的 进程杠开始启动时,所有信号的处理方式要么默认,要么忽略:忽略是 SIGUSR1 和 SIGUSR2 两个信号,其他都采取默认方 ...

  3. 信号屏蔽的切换的理解sigsuspend

    #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h&g ...

  4. Linux C 程序 信号及信号的处理(19)

    信号及信号的处理 1.Linux信号的介绍  信号是一种软件中断.Linux系统中根据POSIX标准扩展的信号机制.  1.信号来源      1.硬件方式           1.当用户按下某个键, ...

  5. Linux系统编程之----》信号

    "===信号========================================================================================= ...

  6. Linux系统编程——进程间通信:信号中断处理

    什么是信号? 信号是 Linux 进程间通信的最古老的方式.信号是url=474nN303T2Oe2ehYZjkrggeXCaJPDSrmM5Unoh4TTuty4wSgS0nl4-vl43AGMFb ...

  7. Linux下shell脚本中信号捕获和函数练习脚本之ping一个网段

    该脚本主要的目的是练习在Linux bash脚本中捕获信号,顺便练习一下函数的使用,还有就是终止一个正在运行的程序后,该程序打开的文件的后续处理问题等等!脚本功能:  ping一个网段内的IP,检测哪 ...

  8. [Linux]返回被阻塞的信号集

    一.概述 在另一篇实例说到,进程可以屏蔽它不想接收的信号集. 事实上这些被屏蔽的信号只是阻塞在内核的进程表中,因为他们不能递送给进程,所以状态是未决的(pending). 利用sigpending函数 ...

  9. linux 进程学习笔记-进程信号sigal

    信号(或软中断)是在软件层次上对中断的一个模拟,其运行在“用户空间”,一个进程对另外一个或几个进程通过发送信号来实现异步通信.当接收进程接收到信号后,其可以注册一下处理函数来说对这些信号进行处理(也可 ...

随机推荐

  1. Educational Codeforces Round 46 (Div 2) (A~G)

    目录 Codeforces 1000 A.Codehorses T-shirts B.Light It Up C.Covered Points Count(差分) D.Yet Another Prob ...

  2. Java并发(二十二):定时任务ScheduledThreadPoolExecutor

    需要在理解线程池原理的基础上学习定时任务:Java并发(二十一):线程池实现原理 一.先做总结 通过一个简单示例总结: public static void main(String[] args) { ...

  3. PAT甲级1131. Subway Map

    PAT甲级1131. Subway Map 题意: 在大城市,地铁系统对访客总是看起来很复杂.给你一些感觉,下图显示了北京地铁的地图.现在你应该帮助人们掌握你的电脑技能!鉴于您的用户的起始位置,您的任 ...

  4. sql中如何统计一字段中字符串的个数

    declare @s varchar(100)set @s='156434A27kAsdABCiosd-01&**('--找出现的次数select len(@s)-len(replace(@s ...

  5. ubuntu 13.04 编译 安装 升级 gcc 4.9.0 address sanitizer

    @ 前记: 最近查一个线上项目的crash,review代码无果,crash几率低,不可在本地环境重现.之后在线上好几个服务器跑valgrind就不crash了.个人猜测可能是跑valgrind后性能 ...

  6. CentOS 6.9配置EPEL源

    简介: EPEL是一个由特别兴趣小组创建.维护并管理的,针对 红帽企业版 Linux(RHEL)及其衍生发行版(比如 CentOS.Scientific Linux.Oracle Enterprise ...

  7. HTTP请求头和响应头

      这篇文章简单总结一下HTTP请求头和响应头,并举一些web开发中响应头的用例. 1. HTTP请求头 accept:浏览器通过这个头告诉服务器,它所支持的数据类型.如:text/html, ima ...

  8. gcc g++支持C++11 标准编译及其区别

    g++ -g -Wall -std=c++11 main.cpp gcc -g -Wall -std=c11 main.cpp 如果不想每次写这个-std=C++11这个选项该怎么办呢? 方法出处:h ...

  9. 我对NHibernate的感受(3):有些尴尬的集合支持

    既然是一个ORM框架,那么自然是将O这一端映射R上.至于集合,是O这方面最常见,也是R这一边非常容易表示的关系.例如,一个问题(Question)可以包含多个回答(Answer),于是我的代码里就有这 ...

  10. JDBC 连Sql Server 接数据库--The TCP/IP connection to the host localhost, port 1433 has failed

    原文:https://blog.csdn.net/qq_39241986/article/details/80848855 这样的错误,你有遇到过吗? The TCP/IP connection to ...