执行信号的处理动作称为信号递达(Delivery),信号从产生到递达之间的状态,称为信号未决(Pending)

进程可以选择阻塞(Block)某个信号。被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。注意,阻塞和忽略是不同,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作

1:PCB进程控制块中函数有信号屏蔽状态字(block)信号未决状态字(pending)还有是否忽略标志(或是信号处理函数);block状态字、pending状态字 64bit;

2:信号屏蔽状态字(block),1代表阻塞、0代表不阻塞;信号未决状态字(pending)的1代表未决,0代表信号可以抵达了;它们都是每一个bit代表一个信号,比如,bit0代表信号SIGHUP;

3:比如向进程发送SIGINT,内核首先判断信号屏蔽状态字是否阻塞,如果该信号被设为为了阻塞的,那么信号未决状态字(pending)相应位制成1;若该信号阻塞解除,信号未决状态字(pending)相应位制成0;表示信号此时可以抵达了,也就是可以接收该信号了。

4:屏蔽状态字用户可以读写,未决状态字用户只能读(?);这是信号设计机制。

信号集操作函数,对状态字进行操作(屏蔽状态字和未决状态字):

#include <signal.h>
int sigemptyset(sigset_t *set);//将信号集清空,共64bits
int sigfillset(sigset_t *set);//将信号集置1
int sigaddset(sigset_t *set, int signum);//将signum对应的位置为1
int sigdelset(sigset_t *set, int signum);//将signum对应的位置为0
int sigismember(const sigset_t *set, int signum);//判断signum是否在该信号集合中,如果集合中该位为1,则返回1,表示位于在集合中
还有一个函数可以读取更改屏蔽状态字的API函数

#include <signal.h>

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

参数how有下面三种取值:
SIG_BLOCK:  将参数set指向的信号集中设置的信号添加到现在的屏蔽状态字中,设置为阻塞;
SIG_UNBLOCK:将参数set指向的信号集中设置的信号添加到现在的屏蔽状态字中,设置为非阻塞, 也就是解除阻塞;
SIG_SETMASK:将参数set指向的信号集直接覆盖现在的屏蔽状态字的值;
如果oset是非空指针,则读取进程的当前信号屏蔽字通过oset参数传出。
若成功则为0,若出错则为-1 还有一个函数可以读取未决状态字(pending)信息 
#include <signal.h>
int sigpending(sigset_t *set);
SIGINT信号设置阻塞,查看未决关键字 
发送SIGINT信号,查看未决关键字 
发送SIGQUIT信号解除SIGINT信号阻塞,查看未决关键字  刚开始设置SIGINT信号为阻塞信号,当按下Ctrl+c发送中断信号SIGINT(值为2,所以后来第二位被置1)之前,未决状态字的所有位都是0,因为此时没有未抵达的信号;
当发送SIGINT信号后,因为该信号是阻塞的,所以未决状态字将第二位置为了1,表示该信号在这里阻塞了;当我按下Ctrl+\发送SIGQUIT信号后,又将SIGINT信号设置为了非阻塞的;
此时可以看到未决状态字的所有位都变为了0;并且也收到了刚才阻塞的SIGINT信号;
#include <iostream>
#include <signal.h>
#include <cstdlib>
#include <unistd.h>
using namespace std; void handler(int num)
{
if(num == SIGINT){
cout << "刚才收到了信号SIGQUIT, 取消了阻塞,收到中断信号.." << endl;
}
else if (num == SIGQUIT){
//将SIGINT信号设置为非阻塞的
sigset_t un_bset;
sigemptyset(&un_bset);
sigaddset(&un_bset, SIGINT);
sigprocmask(SIG_UNBLOCK, &un_bset, NULL);
}
} void print_pending(sigset_t * pset)
{
int i = ;
cout << "未决状态字(64位):";
for (i = ; i <= ; ++i){
if(sigismember(pset, i))
cout << ;
else
cout << ;
if(i % == ){
cout << " ";
}
}
cout << endl;
}
int main()
{
sigset_t bset;
sigset_t pset; //设置SIGINT信号
sigemptyset(&bset);
sigaddset(&bset, SIGINT); signal(SIGINT, handler);
signal(SIGQUIT, handler);
//将SIGINT信号设置为阻塞的
sigprocmask(SIG_BLOCK, &bset, NULL); while(){
//得到未决状态字
sigpending(&pset);
//显示未决状态字
print_pending(&pset); sleep();
} exit();
}
 

linux信号--阻塞与未决的更多相关文章

  1. linux系统编程之信号(五):信号集操作函数,信号阻塞与未决

    一,信号集及相关操作函数 信号集被定义为一种数据类型: typedef struct { unsigned long sig[_NSIG_WORDS]: } sigset_t 信号集用来描述信号的集合 ...

  2. Linux 信号详解五(信号阻塞,信号未决)

    信号在内核中的表示 执行信号的处理动作成为信号递达(Delivery),信号从产生到递达之间的状态称为信号未决(Pending).进程可以选择阻塞(Block)某个信号. 被阻塞的信号产生时将保持在未 ...

  3. Linux信号(signal) 机制分析

    Linux信号(signal) 机制分析 [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核 ...

  4. 非常好的一篇对linux信号(signal)的解析 (转载)【转】

    转自:https://blog.csdn.net/return_cc/article/details/78845346 Linux信号(signal) 机制分析 转载至:https://www.cnb ...

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

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

  6. Linux信号(signal)机制【转】

    转自:http://gityuan.com/2015/12/20/signal/ 信号(signal)是一种软中断,信号机制是进程间通信的一种方式,采用异步通信方式 一.信号类型 Linux系统共定义 ...

  7. Linux信号机制

    Linux信号(signal) 机制分析 [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核 ...

  8. Linux信号(signal) 机制分析(转)

    [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核对于信号的处理流程包括信号的触发/注册/执 ...

  9. linux信号-------初涉

    一.信号的本质 软中断信号(signal,又简称为信号)用来通知进程发生了异步事件.在软件层次上是对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的.信号是进程 ...

随机推荐

  1. 我感觉这个书上的微信小程序登陆写得不好

    基本功能是OK,但是感觉传的数据太多,不安全,需要改写. App({ d: { hostUrl: 'http://www.test.com/index.php', //请填写您自己的小程序主机URL ...

  2. AT2000 Leftmost Ball

    设\(f[i][j]\)表示当前有\(i\)个白球,一共放完了\(j\)种球 显然有\(j <= i\) 对于每个状态目前已经放下去的球是固定了的,那么考虑转移 放白球 从\(f[i - 1][ ...

  3. Caused by: org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): com.qingmu.seller.entity.OrderMaster

    org.springframework.orm.jpa.JpaSystemException: ids for this class must be manually assigned before ...

  4. gcc分步骤编译的记录

  5. AtCoder Beginner Contest 129 解题报告

    传送门 写了四个题就跑去打球了.第五题应该能肝出来的. A - Airplane #include <bits/stdc++.h> using namespace std; inline ...

  6. php for循环遍历索引数组

    遍历二字,从字面解释就是一个接一个全读访问一次,显示出来. 因为for循环是一个单纯的计数型循环,而索引数组的下标为整型的数值.因此,我们可以通过for循环来遍历索引数组. 我们知道索引数组下标为整型 ...

  7. 学到了林海峰,武沛齐讲的Day50 django

    http请求中产生两个核心对象: http请求:HttpRequest对象 http响应:HttpResponse对象 所在位置:django.http 5/8结束

  8. Vue之路由

    1. SPA是什么 单页Web应用(single page application,SPA),就是只有一个Web页面的应用, 是加载单个HTML页面,并在用户与应用程序交互时动态更新该页面的Web应用 ...

  9. HAProxy 2.0 and Beyond

    转自:https://www.haproxy.com/blog/haproxy-2-0-and-beyond/  关于haproxy 2.0 的新特性说明 HAProxy Technologies i ...

  10. 推荐一款分布式微服务框架 Surging

    surging   surging 是一个分布式微服务框架,提供高性能RPC远程服务调用,采用Zookeeper.Consul作为surging服务的注册中心,集成了哈希,随机,轮询,压力最小优先作为 ...