首页 > 代码库 > linux下的信号屏蔽字

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;
}

 

linux下的信号屏蔽字