1,由来

让指定的信号无法唤醒进程貌似很简单,只要先设置屏蔽字屏蔽指定的信号,再pause就可以了。以后只要接收到信号,切该信号不是指定的信号就可以结束 pause。但是,这种做法是分两步做的,而信号可以发生在任何时候。如果在设置屏蔽字与pause之间就触发了那个指定的信号怎么办??

所以我们需要一个原子操作的函数来实现这一功能。这就是sigsuspend.

int sigsuspend(const sigset_t* sigmask);

注意:这个函数在正确返回是返回-1.。。。。。

sigmask指定的信号将被屏蔽,无法唤醒进程;而其他信号被捕捉到并从信号处理程序返回后,将唤醒进程,哪怕是之前被屏蔽的信号。

2,例子

int main(){//10.16 sigsuapendsigset_t newmask, oldmask, waitmask;//1,程序开始处打印屏蔽字,应该是什么都没有pr_mask("program start: ");//2,注册3个信号if (signal(SIGINT, sig_int) == SIG_ERR)err_sys("signal error!");if (signal(SIGUSR1, sig_usr) == SIG_ERR)err_sys("signal error!");if (signal(SIGUSR2, sig_usr_new2) == SIG_ERR)err_sys("signal error!");//3,准备屏蔽字sigemptyset(&waitmask); //sigsuspend时的屏蔽字sigaddset(&waitmask, SIGUSR2);sigemptyset(&newmask);  //sigsuspend之前的屏蔽字sigaddset(&newmask,SIGUSR1);//4,屏蔽信号SIGUSR1if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)err_sys("SIG_BLOCK error!");//5,从这里到sigsuspend调用之间都是安全区//   打印安全区的屏蔽字pr_mask("in critical region: ");//6,设置等待,仅仅waitmask指定的信号不能让其退出等待,其他信号都可以if(sigsuspend(&waitmask) != -1)err_sys("sigsuspend error!");//7,上一步的函数在接收到信号后返回,打印返回后的屏蔽字pr_mask("after return from sigsuspend:  ");//8,恢复屏蔽字if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)err_sys("SIG_SETMASK error!");//9,打印回复后的屏蔽字pr_mask("program exit: ");exit(0);
}//针对SIGUSR1的信号处理程序
static void sig_usr(int signo) {printf("received SIGUSR1 %d,, signo =\n", signo);  pr_mask("in sig_usr: ");
}void sig_usr_new2(int signo)
{printf("recived SIGUSR2, signo = %d\n",signo);pr_mask("in sig_usr_new2: ");
}void sig_int(int signo)
{pr_mask("\nin sig_int: ");
}void err_sys(const char *str)
{printf("%s\n",str);exit(1);
}

我们先屏蔽USR1,再通过sigsuspend屏蔽USR2,看看这两者有啥不同。

执行效果:

➜  code g++ -g -W -o study_Linux study_Linux.c
➜  code ./study_Linux &
[1] 559
zsh: nice(5) failed: operation not permitted
program start:
in critical region:     SIGUSR1
➜  code
➜  code kill -USR2 559
➜  code
➜  code kill -USR1 559
received SIGUSR1 10
in sig_usr:     SIGUSR1 SIGUSR2
recived SIGUSR2, signo = 12
in sig_usr_new2:        SIGUSR1 SIGUSR2
after return from sigsuspend:   SIGUSR1
program exit:
[1]  + 559 done       ./study_Linux
➜  code 

我们在调用sigsuspend之前已经屏蔽了SIGUSR1,这一点在in critical region的打印中可以看到;

接下来,由于sigsuspend的执行,程序挂起,等待信号。

我们先向其发送SIGUSR2信号,由于这个信号被sigsuspend指定为该屏蔽的信号,所以我们看到什么都没发生,程序继续挂起;

接下来我们向其发送SIGUSR1信号,虽然这个信号之前是被屏蔽的,但是现在它却被正确地捕获并执行了信号处理程序。

比较诡异的是,我们在信号处理程序中打印当前的屏蔽字,赫然发现SIGUSR1和SIGUSR2都是被屏蔽的?!!

既然这两个都是被屏蔽的,怎么现在我们还接收到了 SIGUSR1 ?!并且之前还接收不到SIGUSR2.。。。。

貌似通过sigprocmask和sigsuspend两种方式屏蔽信号,待遇是不一样的。在由sigsuspend导致的等待期间,我们是只认由sigsuspend指定的信号的。其他的信号哪怕在信号屏蔽字里也不屏蔽!真的很好奇sigsuspend是怎么实现的,居然可以无视进程的信号屏蔽字。

继续。

在从SIGUSR1的信号处理程序返回后,进程马上调用了SIGUSR2的信号处理程序。。。

还记得我们是先发送SIGUSR2,再发送SIGUSR1吧。之前SIGUSR2被屏蔽了,貌似此时已经解除了封印。

在SIGUSR2的信号处理程序中打印出的信号屏蔽字依然是SIGUSR2和SIGUSR1都在。

在这两个信号都处理完之后,进程终于从sigsuspend返回了。返回后进程的屏蔽字会发生变化,它会恢复sigsuspend调用前的屏蔽字,我们看到此时屏蔽字里只剩下SIGUSR1了。

最后一步,再把SIGUSR1的屏蔽也恢复掉。

Linux学习笔记22——sigsuspend 让指定的信号无法唤醒进程相关推荐

  1. 【Linux学习笔记22】mysql数据库的基本管理

    文章目录 1. 数据库的介绍 2. 安装mysql并启用 3. 软件基本信息 4. 数据库的安全初始化 4.1 关闭数据库开放端口 4.2 执行安全初始化脚本 5. 数据库基本管理 5.1 数据库查看 ...

  2. LINUX学习笔记共五部分

    LINUX学习笔记1--LINUX系统命令 1.         界面切换: a)         进入字符界面:按住ctrl+alt+F1: 1.         首先需要进入用户登入,输入用户名和 ...

  3. Linux学习笔记(3)- 网络编程以及范例程序

    Linux学习笔记(3)- 网络编程以及范例程序 前言 网络介绍 IP地址的介绍 端口和端口号的介绍 通信流程 socket介绍 TCP介绍 python3编码转换 TCP客户端程序开发流程 多任务版 ...

  4. LINUX学习笔记:31个常用LINUX命令和相关解释

    LINUX学习笔记三: 最近在带新同事,是一个刚入行的萌新,对于linux不是很熟悉,问我怎么来学习. 所以今天接着之前的部分,继续分享一些linux学习资料.有需要的点点保存,没有跳过呗.PS:内容 ...

  5. Linux学习笔记-随即更新-慢速学习

    Linux学习笔记 Linux系统简介 UNIX发展历史和发行版本 开源软件简介 支撑互联网的开源技术 Linux应用领域 Linux学习方法 Linux系统安装 给初学者的建议 学习linux的注意 ...

  6. 嵌入式linux学习笔记--TCP通讯整理

    嵌入式linux学习笔记–TCP通讯整理 之前的项目中使用到了比较多的tcp 通讯相关的知识,一直也没有进行整理,今天准备拿出时间好好的整理一下TCP通讯的整个过程.预计会整理linux和window ...

  7. 史上最牛最强的linux学习笔记 10.shell基础

    史上最牛最强的linux学习笔记 10.shell基础 写在最前面: 本文是基于某站的视频学习所得,第一个链接如下: https://www.bilibili.com/video/BV1mW411i7 ...

  8. Linux学习笔记---命令篇

    Linux学习笔记-命令篇 本笔记是根据尚硅谷的Linux视频,经过自己的总结得出来的笔记,分为两个大章节,一-四章讲的是Linux的文件目录结构.vim编辑器.网络配置和系统管理.进程和服务.第二个 ...

  9. 大数据开发工程师基本功修炼之史上最全Linux学习笔记(建议)

    我正在参加年度博客之星评选,请大家帮我投票打分,您的每一分都是对我的支持与鼓励. 2021年「博客之星」参赛博主:Maynor大数据 (感谢礼品.红包免费送!) https://bbs.csdn.ne ...

最新文章

  1. 基于HTTP协议的几种实时数据获取技术
  2. 以太坊和Metamask开发web应用时不再需要密码
  3. java互联网架构师入门进阶之路
  4. 新浪微博授权认证过程
  5. AutoMapper用法一瞥
  6. 【JS 逆向百例】Ether Rock 空投接口 AES256 加密分析
  7. 包管理器Bower使用手册之一
  8. Mapreduce 进阶
  9. 在ubuntu安装使用miniconda
  10. usb 驱动之usbip
  11. 如何在Microsoft Word里面插入图片作为背景/封面?
  12. Skype for business之Skype会议直播
  13. PHP电子合同对接流程,电子合同订立程序步骤
  14. HTML压缩(JSP的GZIP实现)
  15. Java Web实现用户注册页面的提交
  16. 『WEB』web学习
  17. 限流对于抖音玩家来说,无异于被宣布了“死亡”。
  18. 第五届蓝桥杯C/C++本科B组(真题试做)(9~10)
  19. 【电针驱动迷走-肾上腺轴的神经解剖学基础】A neuroanatomical basis for electroacupuncture to drive the vagal– adrenal axis
  20. 常见英语面试问题及答案

热门文章

  1. 开发一款智能血压计PCBA方案
  2. 【luogu3950】部落冲突--树剖
  3. 《部落冲突》英雄角色的渲染方式
  4. 如何丰富PPT背景,快收藏这两个技巧
  5. GO语言内存逃逸图文分析
  6. BIEE怎么展示数据库中的空格
  7. 说说anchorPoint
  8. 2021牛客多校6K Starch Cat(点分治+猫树)
  9. Handler机制原理解析(一)
  10. List Dork Google