信号在内核中的表示
执行信号的处理动作成为信号递达(Delivery),信号从产生到递达之间的状态称为信号未决(Pending)。进程可以选择阻塞(Block)某个信号。
被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作
注意:阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作
信号不会丢失,如果信号被阻塞,只会保持信号未决,但是信号不丢失
只要取消阻塞 信号依然会到来
①PCB进程控制块中有信号屏蔽状态字(block),信号未决状态字(pending)还有是否忽略标识
②信号屏蔽状态字(block):1代表阻塞,0代表不阻塞;信号未决状态字(pending):1代表未决,0代表信号递达
③向进程发送SIGINT,内核首先判断信号屏蔽状态字是否阻塞,如果信号屏蔽状态字阻塞,信号未决状态字(pengding)相应位置1;
若阻塞解除,信号未决状态字(pending)相应位置0,表示信号可以递达了。
④block状态字,pending状态都是64bit,分别代表Linux系统中的64个信号。例如SIGINT是2号信号,对应block状态字中的第二位
⑤block状态字用户可以读写,pending状态字用户只能读,这是新号的设计机制。
信号集操作函数(block状态字表示)
#include <signal.h>
int sigemptyset(sigset_t *set);
sigset_t *set实质上是8个字节大小的变量(8个字节64bit,代表Linux的64个信号)
sigemptyset将状态字置零
int sigfillset(sigset_t *set);
sigfillset将状态字全部置1(32号信号和33号信号除外)
int sigaddset(sigset_t *set,int signo);
将信号signo加入到信号集set中
int sigdelset(sigset_t *set,int signo);
将信号signo从信号集中删除
int sigismember(const sigset *set,int signo);
判断signo是否在信号集中
sigprocmask读取或者更改进程的信号屏蔽状态字(block)
#include <signal.h>
int sigprocmask(int how,const sigset_t *set,sigset * oset);
成功返回0,出错返回-
如果oset是非空指针,则读取进程的当前信号屏蔽状态字通过oset参数传出,如果set是非空指针,则更改进程的信号屏蔽状态字,参数how只是如何更改。
如果oset和set都是非空指针,则先将原来的信号屏蔽字备份到oset里,然后根据set和how参数更改信号屏蔽字。
how含义
--SIG_BLOCK set包含了我们希望添加到当前信号屏蔽字的信号,相当于mask=mask|set(位或运算)
--SIG_UNBLOCK set包含了我们希望从当前信号屏蔽字中解除阻塞的信号,相当于mask=mask^set(位异或运算)
--SIG_SETMASK 设置当前信号屏蔽字为set所指向的值,相当于mask=set
int sigpending(sigset_t *set);
获取信号未决状态字(pending)信息
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h> void printsigset(const sigset_t *pset)
{
int i = ;
//遍历64个信号,
for (; i < ; i++)
{
//信号从1开始 判断哪些信号在信号未决状态字中
if (sigismember(pset, i + ))
putchar('');
else
putchar('');
//fflush(stdout);
}
printf("\n");
} void catch_signal(int sign)
{
switch (sign)
{
case SIGINT:
printf("accept SIGINT!\n");
exit();
break;
case SIGQUIT:
printf("accept SIGQUIT!\n");
//取消信号阻塞
//定义信号集
sigset_t uset;
//清空信号集
sigemptyset(&uset);
//将SIGINT信号加入到信号集中
sigaddset(&uset,SIGINT);
//进行位异或操作,将信号集uset更新到进程控制块PCB结构中,取消阻塞信号SIGINT
sigprocmask(SIG_UNBLOCK,&uset,NULL);
break;
}
} int main(int arg, char *args[])
{
//定义未决信号集(pending)
sigset_t pset;
//定义阻塞信号集(block)
sigset_t bset;
//清空信号集
sigemptyset(&bset);
//将信号SIGINT加入到信号集中
sigaddset(&bset, SIGINT);
//注册信号
if (signal(SIGINT, catch_signal) == SIG_ERR)
{
perror("signal error");
return -;
}
if (signal(SIGQUIT, catch_signal) == SIG_ERR)
{
perror("signal error");
return -;
}
//进行位或操作,将信号集bset更新到进程控制块PCB结构中,阻塞信号SIGINT(即使用户按下ctrl+c,信号也不会递达)
sigprocmask(SIG_BLOCK, &bset, NULL);
while ()
{
/*
* 获取当前信号未决信息,即使在sigprocmask()函数中设置了信号阻塞,
* 但是如果没有信号的到来,信号未决状态字对应位依然是0
* 只要有信号到来,并且被阻塞了,信号未决状态字对应位才会是1
* */
sigpending(&pset);
//打印信号未决信息
printsigset(&pset);
sleep();
}
return ;
}

Linux 信号详解五(信号阻塞,信号未决)的更多相关文章

  1. Linux 信号详解六(可靠信号与不可靠信号)

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

  2. 第三百五十五节,Python分布式爬虫打造搜索引擎Scrapy精讲—scrapy信号详解

    第三百五十五节,Python分布式爬虫打造搜索引擎Scrapy精讲—scrapy信号详解 信号一般使用信号分发器dispatcher.connect(),来设置信号,和信号触发函数,当捕获到信号时执行 ...

  3. SIGPIPE信号详解

    转自:http://blog.csdn.net/lmh12506/article/details/8457772 前一段面试的时候被问到项目中有没有处理SIGPIPE信号,怎么处理的?当时没有答出来, ...

  4. Linux 系统结构详解

    Linux 系统结构详解 Linux系统一般有4个主要部分: 内核.shell.文件系统和应用程序.内核.shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序.管理文件并使用系统 ...

  5. (转)Linux PS 详解

    原文:https://cn.aliyun.com/jiaocheng/162702.html 摘要:原文地址:http://www.cnblogs.com/wangkangluo1/archive/2 ...

  6. Linux init详解(转)

    Linux init详解 一.什么是INIT: init是Linux系统操作中不可缺少的程序之一. 所谓的init进程,它是一个由内核启动的用户级进程. 内核自行启动(已经被载入内存,开始运行,并已初 ...

  7. pika详解(五)登录认证及connectionParameters

    pika详解(五)登录认证及connectionParameters 本文链接:https://blog.csdn.net/comprel/article/details/94662916 版权 pi ...

  8. Linux命令详解之—tail命令

    tail命令也是一个非常常用的文件查看类的命令,今天就为大家介绍下Linux tail命令的用法. 更多Linux命令详情请看:Linux命令速查手册 Linux tail命令主要用来从指定点开始将文 ...

  9. Linux命令详解之—less命令

    Linux下还有一个与more命令非常类似的命令--less命令,相比于more命令,less命令更加灵活强大一些,今天就给大家介绍下Linux下的less命令. 更多Linux命令详情请看:Linu ...

随机推荐

  1. 使用xmarks同步 chrome ie firefox safari书签

    xmarks是什么? Install Xmarks on each computer you use, and it seamlessly integrates with your web brows ...

  2. iis中限制访问某个文件或某个类型的文件配置方法

    Note:此处不是权限设置问题,此处不是权限设置问题,此处不是权限设置问题!只是出于数据或者网络安全,禁止扫描工具直接扫描到某些包含敏感信息的文件,尤其比如日志.配置等 默认ASP.NET已经考虑到了 ...

  3. 如何利用Pre.im分发iOS测试包

    大众创新万众创业,在移动互联网的风口,移动APP开发与测试发展方兴未艾,受到了越来越多的重视.相较 iOS,Android 的开发环境更加开放.Android 开发者要测试应用时,只需发个 APK 安 ...

  4. get set 中 快捷键生成的get方法中 renturn 没有 this.对象 中的this 解决方法

    选EDIT  进行修改

  5. JavaScript(一)——简介(简单介绍)

    1.JavaScript是个什么东西? 它是个脚本语言,需要有宿主文件,它的宿主文件是HTML文件. 2.它与Java什么关系? 没有什么直接的联系,Java是Sun公司(已被Oracle收购了),J ...

  6. (1)编写一个接口ShapePara,要求: 接口中的方法: int getArea():获得图形的面积。int getCircumference():获得图形的周长 (2)编写一个圆类Circle,要求:圆类Circle实现接口ShapePara。 该类包含有成员变量: radius:public 修饰的double类型radius,表示圆的半径。 x:private修饰的double型变量x,

    package com.hanqi.test; //创建接口 public interface ShapePara { //获取面积的方法 double getArea(); //获取周长的方法 do ...

  7. .NET框架设计(常被忽视的框架设计技巧)

    阅读目录: 1.开篇介绍 2.元数据缓存池模式(在运行时构造元数据缓存池) 2.1.元数据设计模式(抽象出对数据的描述数据) 2.2.借助Dynamic来改变IOC.AOP动态绑定的问题 2.3.元数 ...

  8. JSP与Servelt的区别

    相同点: 两者都是服务端的技术,而JSP本质上就是Servelt: 都可以处理来自客户端的请求,都可以对请求作出响应: 都可以生成HTML页面返回. 不同点: 在实际开发中,对JSP编程成响应的HTM ...

  9. 烂泥:KVM、kickstart与nginx集成

    本文由秀依林枫提供友情赞助,首发于烂泥行天下. 前几篇文章介绍了FTP.NFS与KVM.kickstart集成的案例,从这篇文章开始,我们来介绍HTTP方式与KVM.kickstart集成. HTTP ...

  10. 解决mstsc无法连接问题:由于没有远程桌面授权服务器可以提供许可证

    一.故障案例① 今天上午在给测试组的IIS新增https的时候,发现远程弹出如下错误: 由于没有远程桌面授权服务器可以提供许可证,远程会话被中断.请跟服务器管理员联系. 度了度,原来也是很常见的一种错 ...