信号的注册、信号的注册

信号的注册(修改信号pending位图)

  • 信号记录在进程pcb中;
  • 信号集合:sigset_t 结构体(保存信号):进程记录一个信号时是通过这个结构体的位图来记录的(1号信号在位图第0位置存储,位图的该位置原本是0,如果有信号,该位置置1),这个位图的位数+1代表的就是指定 的信号存储位置。

信号的阻塞与屏蔽

在pcb中有一个pending结构体存储当前收到的信号,还有一个结构体blocked用于存储现在都有哪些信号要被阻塞。
这里写图片描述
进程看到pending集合都收到了哪些信号,然后就要开始处理这些信号,但是在处理这些信号之前,进程会先对比一下这些信号有没有存在于blocked集合中,如果存在就意味着这个信号将不被处理,直至阻塞解除。

sigprocmask:(可以读取或者更改进程的阻塞信号集)
#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
  • how: 对集合所做的操作
  • SIG_BLOCK :对set集合中的信号进行阻塞(将set集合中的信号放在blocked集合中,位图置1),将原有阻塞信号放在oldset集合进行保存
  • SIG_UNBLOCK:对Set集合中的信号进行解除阻塞(将set集合中的信号在blocked集合中位图置0);oldset忽略
  • SIG_SETMASK :将set集合中的信号设置到blocked集合中,oldset忽略
sigemptyset:
#include <signal.h>
int sigemptyset(sigset_t *set);
功能:清空集合数据,使其中所有信号的对应bit清零,表示该信号集不包含任何有效信号,防止出现意外;
sigemptyset:
#include <signal.h>
int sigemptyset(sigset_t *set);
功能:清空集合数据,使其中所有信号的对应bit清零,表示该信号集不包含任何有效信号,防止出现意外;
sigfillset:
#include <signal.h>
int sigfillset(sigset_t *set);
功能:将所有信号添加到set集合中,使其中所有信号的对应bit置位;
sigaddset:
#include <signal.h>
int sigaddset(sigset_t *set, int signum);
功能:向set集合中添指定的signum信号。
sigdelset:
#include <signal.h>
int sigdelset(sigset_t *set, int signum);
功能:在set集合中删除指定的signum信号。
sigpending:
#include <signal.h>
int sigpending(sigset_t *set);
功能:将当前pending集合(信号注册集合)中的不处理(阻塞信号)信号取出来放到set中;
sigismember:
#include <signal.h>
int sigismember(const sigset_t *set, int signum);
功能:判断指定信号是否存在于指定集合中,存在返回真,不存在返回假。
//这是一个验证信号阻塞屏蔽的代码

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>

int main()
{
        sigset_t mask;
        //   int sigemptyset(sigset_t *set);  清空mask集合
        sigemptyset(&mask);
        //    int sigaddset(sigset_t *set, int signum); 向集合mask中添加指定信号
        sigaddset(&mask,SIGINT);//向集合mask中添加SIGINT信号
        sigset_t oldset;
        sigemptyset(&oldset);
        // int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
        sigprocmask(SIG_BLOCK,&mask,&oldset); //将mask中信号进行阻塞放在blocked集合中
        //将SIGINT解除阻塞
        //getchar(); //回车后就会解除阻塞
       // sigprocmask(SIG_UNBLOCK,&mask,NULL);
       //或者 sigprocmask(SIG_SETMASK,&oldmask,NULL);  
        while(1)
        {
                printf("this is proc mask\n");
                sleep(1);
                sigset_t set;
                sigemptyset(&set);
                //   int sigpending(sigset_t *set);//如果终端输入的信号中有被阻塞的信号则放在set中
                sigpending(&set);
                int i=0;
                for(i=1;i<64;i++)
                {
                        //   int sigismember(const sigset_t *set, int signum);
                        if(sigismember(&set,i)) //判断指定信号是否存在于指定集合中
                                printf("signo:%d\n",i);
                }
        }
       return 0;
}

这里写图片描述
ctrl+c即2号信号SIGINT,由于对SIGINT信号阻塞,那么就会把SIGINT放进set中。
信号的注销

这里写图片描述

猜你喜欢

转载自blog.csdn.net/sophia__yu/article/details/82319672