信号的表示
我们知道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