信号的阻塞

一. 阻塞信号

1.信号的相关概念
    (1) 递达: 实际执行信号的处理动作称为信号的递达
    (2) 未决: 信号从产生到递达之间的过程叫做信号的未决
    (3) 阻塞: 进程可以选择阻塞某个信号, 被阻塞的信号产生时将保持在未决状态, 直到进程解除该信号的屏蔽, 才执行递达动作.
    (4) 阻塞和忽略的不同: 信号被阻塞就不会被递达, 而信号被忽略是该信号递达的一种方式
    (5) 信号递达的几种方式: 忽略, 默认处理, 自定义

二. 信号在内核中的表示

    这里写图片描述
    每个信号都有两个标志位表示该信号的阻塞和未决还有一个函数指针表示该信号的处理动作, 信号产生时,内核在进程控制块中设置该信号的未决标识, 直到该信号递达才清除该标志. 在图上 SIGUP 信号未产生过, 也为阻塞过, 当它递达时执行默认动作, SIGINT 信号产生过, 并且处于阻塞状态, 该信号暂时不能被递达, 直到被解除阻塞. SIGQUIT 未产生, 一旦产生, 该信号就被阻塞, 它的处理动作是自定义. 如果在进程解除对某信号的阻塞前, 信号产生过多次, 该信号该怎样计算呢? POSIX.1 允许信号被递达一次或者多次, Linux 中规定对于普通信号, 在递达之前产生多次知己一次, 而对于实时信号递达多次可以放在一个队列里.

三. sigset_t

    由图中可以看出, 每个信号只有一个 bit 位表示未决, 一个bit 位表示阻塞, 于是可以用 sigset_t 的数据类型来对两者进行存储. sigset_t 它是一个信号集, 用来表示该信号的有效或者无效. 在阻塞表中表示是否阻塞, 在未决表中表示该信号是否未决.阻塞信号集也叫做当前信号的屏蔽字

四. 相关接口函数

    1.信号集相关接口
                      这里写图片描述
    (1)用于初始化set 所指向的所有信号集, 将 set 所指向的信号集中的所有信号的 bit 全部清零, 表示该信号集不含任何有效信号.
    (2)sigfillset 用于初始化set信号集所指向的所有信号, 将其中所有信号的 bit 位置位, 该信号集的有效信号包括该系统中支持的所有信号
    (3)使用 sigset_t 类型的 变量的时候一定要用 sigsetempty 以及 sigfillset 初始化, 使得信号集处于确定状态, 初始化之后就可以调用 sigaddset 和 sigdelset 在该信号集中添加或者删除 某个信号
    (4) sigismember 用来判断某个信号集中是否包含某个信号, 如果有返回 1, 没有返回 0, 调用失败返回 -1.
    (5)不能对 sigset_t 类型的变量做任何解释, 如打印等操作, 因为它是系统实现的使用者不必关心
    2. 阻塞信号集相关接口
    这里写图片描述
    (1)用来读取或者更改信号屏蔽字(阻塞的信号集), 成功时返回0, 出错时返回 -1.
    (2)how 用来表示更改屏蔽字的方式
    (3)oldset 表示原有的阻塞信号集(信号屏蔽字), set 表示需要修改的信号屏蔽字(阻塞信号集).
    how 有三个取值, 假设当前的屏蔽字是mask 则SIG_BLOCK 相当于 mask = mask | set, SIG_UNBLOCK 相当于 mask = mask &~set, SIG_SETMASK 相当于 mask = set
    3. 未决信号集相关接口
                    这里写图片描述
    用于读取当前进程的未决信号集, set 是一个输出型参数, 有用户自己设定. 调用成功返回0, 调用失败返回 -1.
    4. 代码演示

#include<stdio.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>void sigprint(sigset_t* set)
{if(set == NULL){return;}int i = 0;for(; i < 32; i++){if(sigismember(set, i)){putchar('1');}else{putchar('0');}}printf("\n");
}int main()
{sigset_t set, p;sigset_t oset;sigemptyset(&p);sigemptyset(&set);sigaddset(&set, SIGINT);sigprocmask(SIG_BLOCK, &set, &oset);int count = 10;while(count){sigpending(&p);sigprint(&p);sleep(1);count--;}sigprocmask(SIG_BLOCK, &oset, NULL);return 0;
}

                        这里写图片描述
    此时发现当按 Ctrl + C 的时候进程不能停止, 因为Ctrl + C 是2 号信号, 该信号被阻塞, 当产生一个二号信号时, 操作系统将其放到未决状态, 不能被递达, 因此 Ctrl + C 已经能再终止进程, 当按一下 Ctrl + \ (3)号信号,可以终止进程, 因为该进程没有被阻塞.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/384071.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

信号的捕捉以及SIGCHLD信号

一. 信号的捕捉定义 用户提供一个处理函数, 要求内核在处理信号时必须切换到用户态,执行这个函数, 这种方式就叫做信号的捕捉 二. 图解信号的捕捉过程 1. 由上图可以看出,当处理信号的执行动作时用户自定义的时候,此时就需返回该函数去调用该函数, 这就叫做信号的捕捉. 以前我…

最小栈的实现

所谓最小栈, 就是当前栈顶元素最小, 我们可以这样做, 每次在入栈之前, 将待入栈元素与栈顶元素相比, 每次现将待入栈的元素先入栈, 再将带入栈的元素和较小的元素入栈, 这样就可以保证每次栈顶元素是最小元素. 在出栈的时候规定每次出栈两个元素,这样就可以保证在出栈之后栈顶元…

用C++实现单链表的创建、逆置和输出 的两种方法

http://blog.csdn.net/lfeng_coding/article/details/47300563 题目描述&#xff1a;在已知单链表头节点的情况下&#xff0c;设计算法逆置单链表并输出 方法一&#xff1a;采用首先将头节点指向空&#xff0c;让其变为尾节点&#xff0c;然后利用中间节点 p、q 将其后的节点一…

两个栈实现一个队列

利用两个栈实现一个队列思路是这样的. 首先这个队列包含两个栈, 然后一个栈用来入队列, 一个栈用来出队列 typedef struct QueBy2Stack {SeqStack input;SeqStack output; }QueBy2Stack; 1. 初始化 void QueBy2StackInit(QueBy2Stack* stack) {if(stack NULL){return;//非法…

Linux--线程死锁

http://blog.csdn.net/gebushuaidanhenhuai/article/details/73799824 线程为什会死锁&#xff1f;&#xff1f;“锁”又是什么东西&#xff1f;我们这篇博客主要讲一下为什么要给线程加锁&#xff0c;为什么会出现线程死锁&#xff0c;线程死锁怎么解决。 互斥锁 在我的上篇博…

两个队列实现一个栈

用两个队列实现一个栈的原理是这样的. 规定两个队列, 必须有一个队列是非空, 一个队列是空.每次入栈时必须往非空队列中入, 而每次出栈时, 必须将非空队列里的元素装到空队列中, 直到非空队列中只有一个元素时, 此时就将剩下的这个元素出栈即可. 而取栈顶元素时, 和出栈一样, 先…

Linux--生产者与消费者

http://blog.csdn.net/gebushuaidanhenhuai/article/details/74011636 基本概念 提到生产者和消费者&#xff0c;我们最有可能想到的是商店卖东西&#xff0c;顾客在货架上(缓冲区&#xff09;买东西。 生产者消费者问题&#xff0c;其实是一个多线程同步问题的经典案例。该问…

进程的挂起以及可重入函数

相关接口     pause 函数用于将进程挂起. 如果信号的处理动作是终止进程, 则进程终止, pause 函数没有返回值; 如果信号的处理动作是忽略, 则进程被挂起, pause函数不返回, 如果信号的处理动作是捕捉, 则调用信号处理动作之后pause 返回 -1.来看一段代码 #include<s…

gdb调试多进程程序

1.gdb下调试多进程程序只需要以下几条命令即可              除此之外还可以查看正在调试的进程 info inferiors, 同时也可以将当前正在调试的进程切换到另外一个进程中让其取运行     2.代码调试演示 #include<stdio.h> #include<stdlib.h> #…

关于memcpy和memmove两函数的区别

http://blog.csdn.net/caowei840701/article/details/8491836 [cpp] view plaincopy <p> 关于memcpy和memmove两个c标准库函数&#xff0c;其功能都是将一块内存区域中的指定大小内容复制到目标内存中&#xff0c;在翻阅c标准库实现的源代码我们发现他们是有区别的。&…

判断字符串出栈合法性

先来看说一下思路 接下来就是写代码了 int StackOrder(SeqStack* stack, char* input, char* output, int size_input, int size_output) {if(stack NULL || input NULL || output NULL){return 0;}int i_input 0;int j_output 0;SeqStackType value;for(; j_output <…

共享栈

1.定义 所谓共享栈就是利用一个数组实现两个栈. 先来看一下共享栈的数据结构 typedef struct SharedStack {int top1;int top2;SeqStackType* data; }SharedStack; 2. 初始化 void SharedStackInit(SharedStack* stack) {if(stack NULL){return;//非法输入}stack -> top…

迷宫求解(递归)

首先来看一下迷宫简易图                                  我们用 0 来表示该位置是墙, 用 1 来表示该位置是路. 所以, 我们在处理迷宫问题的时候可以将其看成一个二维数组即可, 而对应的每一条路我们可以用坐标的形式将其表示, 所以还需要…

数据结构练习——双向链表

http://www.cnblogs.com/-Lei/archive/2012/04/10/2440399.html 复习一下数据结构。。。。说不准下个星期就用上了 只不过写的很简单&#xff0c;没有封装 DoubleLinkList.h #ifndef GUARD_DoubleLinkList_h #define GUARD_DoubleLinkList_h#include <stdio.h>struct Li…

线程的终止分离

1.线程的终止 注意该函数是针对用户级别的, 其中 retal 必须指向一个全局变量, 或者是一个 malloc 分配的, 因为如果是线程的局部变量, 当该线程退出时, 其他线程不能得到这个变量, 因为线程的局部变量各自私有 2. 现成的取消 其中thread是线程的 tid 3.线程的等待与分离 (1)…

C语言中的深拷贝和浅拷贝

http://www.cnblogs.com/zhanggaofeng/p/5421804.html C语言中的深拷贝和浅拷贝 //C语言中的深拷贝和浅拷贝 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h>typedef struct _student{char name[30];char *title;…

死锁的产生和避免

1.死锁产生的四个必要条件 (1)互斥条件&#xff1a;资源是独占的且排他使用&#xff0c;进程互斥使用资源&#xff0c;即任意时刻一个资源只能给一个进程使用&#xff0c;其他进程若申请一个资源&#xff0c;而该资源被另一进程占有时&#xff0c;则申请者等待直到资源被占有者…

gethostbyname() 函数说明

https://www.cnblogs.com/cxz2009/archive/2010/11/19/1881611.html gethostbyname()函数说明——用域名或主机名获取IP地址 包含头文件#include <netdb.h>#include <sys/socket.h>函数原型struct hostent *gethostbyname(const char *name);这个函数的传入值是域…

求解迷宫最短路径

1. 多通路迷宫初始化 先构建一个多通路迷宫,并且对其初始化 void MazeInitShortPath(Maze* maze) {if(maze NULL){return;}int row 0;int col 0;for(; row < MAX_COL; row){for(col 0; col < MAX_COL; col){maze -> map[row][col] Map[row][col];}printf("…

带环迷宫求最短路径

前面介绍了简单的迷宫求解问题, 今天我们就对带环迷宫求出它的最短路径 1.首先来看一个带环迷宫的简单地图 在这张迷宫地图中,我们规定入口点的位置entry的坐标是 (0, 1), 同时, 我们给入口点传一个非法坐标,作为入口点的前一个位置(-1, -1). 接下来的思路就和上一篇的思路是一…