linux下的信号屏蔽字

信号的表示

  我们知道linux下,可以通过kill命令向进程发送信号.

  当进程收到信号,执行处理动作被称为递达;

  当进程接收到信号,还未来得及处理被称之为未决(pending);

  进程可以选择阻塞某个信号,当某个信号被阻塞(block)时,永远不会递达!

  因此,与这三种处理相对应,在进程的pcb中,存在三张位图来描述信号相关信息!

block、pending与handler

  block是一个位图,如果某个信号block为1,则表示其永远也不会递达,也就是说永远都不会执行handler表中的函数.

  pending也是一个位图,如果某个信号pending为1,表示其已经产生,如果为0,表示没有产生.

  handler指针数组,表示某个信号处理时的默认动作,SIG_DFL表示默认处理,SIG_IGN表示忽略该信号,其它表示自定义处理.

信号的屏蔽与恢复

  知道了这些,我编写了一个程序,来验证一下屏蔽、恢复屏蔽一个信号.

////////////////////////////////////
//文件说明:pending.c
//作者:高小调
//创建时间:2017年06月28日 星期三 15时15分45秒
//开发环境:Kali Linux/g++ v6.3.0
////////////////////////////////////
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<stdlib.h>
//屏蔽SIGINT
void blockSIGINT(){
	sigset_t set;
	sigemptyset(&set);
	sigaddset(&set,SIGINT);
	sigprocmask(SIG_BLOCK,&set,NULL);
}
//恢复SIGINT
void recoverSIGINT(){
	sigset_t set;
	sigemptyset(&set);
	sigprocmask(SIG_SETMASK,&set,NULL);
}
//打印未决表
void printPending(sigset_t *set){
	for(int i=1; i<=31; ++i){
		if(sigismember(set,i)){
			putchar(‘1‘);
		}else{
			putchar(‘0‘);
		}
	}
	putchar(‘\n‘);
}
void handler(int sig){
	printf("the No.%d signal is deliver!\n",sig);
}
int main(){
	signal(SIGINT,handler);
	int count = 5;
	printf("block the SIGINT %ds later!\n",count);
	sigset_t set;
	sigemptyset(&set);
	//先将SIGINT屏蔽掉
	while(1){
		if(count==0){
			blockSIGINT();
			printf("SIGINT has benn blocked!\n");
			break;
		}
		sigpending(&set);
		printPending(&set);
		sleep(1);
		--count;
	}
	//再把它恢复过来
	printf("recover the SIGINT %ds later!\n",10-count);
	while(1){
		if(count==10){
			recoverSIGINT();
			printf("SIGINT has been recovered!\n");
			break;
		}
		//恢复之前,信号被阻塞,因此如果产生SIGINT信号,将会处于未决状态
		sigpending(&set);
		printPending(&set);
		count++;
		sleep(1);
	}
	while(1);
	return 0;
}
时间: 2024-09-30 16:26:51

linux下的信号屏蔽字的相关文章

linux下 signal信号机制的透彻分析与各种实例讲解

转自:http://blog.sina.com.cn/s/blog_636a55070101vs2d.html 转自:http://blog.csdn.net/tiany524/article/details/17048069 首先感谢上述两位博主的详细讲解. 虽然内容有点长,但是分析的很全面,各种实例应用基本都考虑到了. 本文将从以下几个方面来阐述信号: (1)信号的基本知识 (2)信号生命周期与处理过程分析 (3) 基本的信号处理函数 (4) 保护临界区不被中断 (5) 信号的继承与执行 (

APUE学习笔记——10.11~10.13 信号集、信号屏蔽字、未决信号

如有转载,请注明出处:Windeal专栏 首先简述下几个概念的关系: 我们通过信号集建立信号屏蔽字,使得信号发生阻塞,被阻塞的信号即未决信号. 信号集: 信号集:其实就是一系列的信号.用sigset_t set表示. 数据类型:sigset_t 类似于整型(位数可能超过整型,因而不能用整型表示). 我们一般在sigprocmask()等函数中使用信号集,用于创建一系列进程要阻塞的信号,告诉内核不允许这些信号发生. 几个关于信号集的函数: #include <signal.h> int sige

UNIX环境编程学习笔记(24)——信号处理进阶学习之信号集和进程信号屏蔽字

lienhua342014-11-03 1 信号传递过程 信号源为目标进程产生了一个信号,然后由内核来决定是否要将该信号传递给目标进程.从信号产生到传递给目标进程的流程图如图 1 所示, 图 1: 信号产生.传递到处理的流程图 进程可以阻塞信号的传递.当信号源为目标进程产生了一个信号之后,内核会执行依次执行下面操作, 1. 如果目标进程设置了忽略该信号,则内核直接将该信号丢弃. 2. 如果目标进程没有阻塞该信号,则内核将该信号传递给目标进程,由目标进程执行相对应操作. 3. 如果目标进程设置阻塞

信号屏蔽字

1. 概念: 信号屏蔽字就是进程中被阻塞的信号集, 这些信号不能发送给该进程, 它们在该进程中被"屏蔽"了. 后面我们会提到, 实际上它们是被阻塞了. 2. 信号屏蔽函数: #include int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oset); 成功则返回0, 出错则返回-1.sigprocmask函数有3个参数: how: 修改信号屏蔽字的方式. set: 把这个信号集设为新的

Linux下捕捉信号

关于 信号signal的知识铺垫 点这里 信号由三种处理方式: 忽略 执行该信号的默认处理动作 捕捉信号 如果信号的处理动作是用户自定义函数,在信号递达时就调用这个自定义函数,这称为捕捉信号. 进程收到一个信号后不会被立即处理,而是在恰当时机进行处理!即内核态返回用户态之前 ! 但是由于信号处理函数的代码在用户空间,所以这增加了内核处理信号捕捉的复杂度. 内核实现信号捕捉的步骤: 用户为某信号注册一个信号处理函数sighandler. 当前正在执行主程序,这时候因为中断.异常或系统调用进入内核态

Linux下异常信号

我们介绍一些标准信号的名称以及它们代表的事件.每一个信号名称是一个代表正整数的宏,但是你不要试图去推测宏代表的具体数值,而是直接使用名称.这是因为这个数值会随不同的系统或同样系统的不同版本而不同,但是名称还算是标准化和统一的.    这些名称定义在signal.h中.    int NSIG是一个定义的宏,它描述了定义的信号的数量.由于信号的数值是从0开始连续分配的,所以,NSIG比系统中所定义的最大的信号数值大1. 11.2.1 程序出错信号    下面介绍的信号是有程序的错误造成的.这些严重

Linux 下信号理解(一)

Linux提供了信号传递进程消息的机制,什么是信号?它是一种非常短的消息,短到只有一个数字.值得强调的是信号和信号量只少了一个字,但他们完全是不同的概念,信号量仅用于同步代码段,而信号则用于传递消息. 一 .信号的编号:通过kill -l 命令可以看到 二.信号机制 可以通过man 7 signal 三.几种默认处理信号的方式: Term表示终止当前进程. Core表示终止当前进程并且Core Dump 生成core文件用于调试(Core Dump 用于gdb调试). Ign表示忽略该信号. S

Linux下信号

信号和 中断是很类似的,只不过是一个是硬件中断,另外一个是软中断.中断是系统对于异步事件的响应. 简单理解就是:中断源 发出 中断信号 在 中断向量表 中执行 中断处理程序 之前保存 现场信息 异步事件的响应:进程执行代码的过程中可以随时被打断,然后去执行异常处理程序. 中断源发出中断信号,CPU判断中断是否屏蔽屏蔽.保护现场 ,cpu执行中断处理程序, cpu恢复现场,继续原来的任务. 中断向量表保存了中断处理程序的入口地址. 中断个数固定,操作系统启动时初始化中断向量表. 中断有优先级,中断

浅谈Linux中的信号机制(二)

首先谢谢 @小尧弟 这位朋友对我昨天夜里写的一篇<浅谈Linux中的信号机制(一)>的指正,之前的题目我用的“浅析”一词,给人一种要剖析内核的感觉.本人自知功力不够,尚且不能对着Linux内核源码评头论足.以后的路还很长,我还是一步一个脚印的慢慢走着吧,Linux内核这座山,我才刚刚抵达山脚下. 好了,言归正传,我接着昨天写下去.如有错误还请各位看官指正,先此谢过. 上篇末尾,我们看到了这样的现象:send进程总共发送了500次SIGINT信号给rcv进程,但是实际过程中rcv只接受/处理了1