2022-1-23 牛客C++项目 —— 信号集及其相应的函数

阻塞信号集和未决信号集
1、用户通过键盘 Ctrl + C,产生 2 号信号 SIGINT(信号被创建)
2、信号产生但是没有被处理(未决状态)

  • 在内核中所有的没有被处理的信号存储在一个集合当中(PCB 当中的未决信号集)
    • SIGINT 未决信号,2号信号被存储在第二个标志位上。
    • 这个标志位的值为 0 ,说明信号不是未决状态
  • 这个标志位的值为 1, 说明信号是未决状态

3、这个未决信号需要被处理,在处理之前需要和另一个信号集(阻塞信号集)进行比较

  • 阻塞信号集默认不阻塞任何信号(也是就是阻塞信号集的每一个位置都是 0 。若为 1 ,则表示需要阻塞。)
  • 如果想要某些信号需要系统调用 API

4、在处理的时候和阻塞信号集中的标志位进行查询,看该信号是否被设置为阻塞的状态。

  • 如果被阻塞了,信号继续处于未决状态,直到阻塞解除,信号就被处理
  • 如果信号没有被阻塞,则信号被处理

为什么需要阻塞信号?
程序运行需要符合一定的逻辑(比如一系列动作的原子操作),如果不阻塞,便会影响到阻塞信号的逻辑。

信号集操作相关的函数的系统调用

/*
#include <signal.h>

int sigemptyset(sigset_t *set);
-功能:清空信号集,将信号集中所有的标志位置为 0 
(sigset_t 是一个64位的整数)
(我的困惑,为什么不能自己直接手动设置为 0 呢?非得弄一个函数)
-参数:set,传出参数,需要操作的信号集
-返回值:成功0,失败-1并设置错误号erron

int sigfillset(sigset_t *set);
-功能:清空信号集,将信号集中所有的标志位置为 1 
(sigset_t 是一个64位的整数)
(我的困惑,为什么不能自己直接手动设置为 0 呢?非得弄一个函数)
-参数:set,传出参数,需要操作的信号集
-返回值:成功0,失败-1并设置错误号erron

int sigaddset(sigset_t *set, int signum);
-功能:设置信号集的某一个标志位为1,表示阻塞这个信号
(sigset_t 是一个64位的整数)
(我的困惑,为什么不能自己直接手动设置为 0 呢?非得弄一个函数)
-参数:set,传出参数,需要操作的信号集
-返回值:成功0,失败-1并设置错误号erron

int sigdelset(sigset_t *set, int signum);
-功能:设置信号集的某一个标志位为0,表示不阻塞这个信号
(sigset_t 是一个64位的整数)
(我的困惑,为什么不能自己直接手动设置为 0 呢?非得弄一个函数)
-参数:set,传出参数,需要操作的信号集
-返回值:成功0,失败-1并设置错误号erron

int sigismember(const sigset_t *set, int signum);
-功能:判断某个信号是否会被阻塞
-参数:set 指定的信号集
       signum 需要判断的那个信号 
-返回值:1表示被阻塞,0表示不阻塞,-1表示调用失败

上述的信号集都是对自定义的信号进行操作
*/
#include<stdio.h>
#include<signal.h>
#include<stdlib.h>
int main(void){
    //创建一个新的信号集
    sigset_t set;

    //清空信号集
    int ret = sigemptyset(&set);
    if(ret == -1){
        perror("sigemptyset");
        exit(0);
    }

    //判断 SIGINT 是否在信号集当中
    ret = sigismember(&set,SIGINT);
    if(ret == -1){
        perror("sigismember-SIGINT");
        exit(0);
    }
    else if(ret == 0){
        printf("SIGINT 不阻塞\n");
    }
    else if(ret == 1){
        printf("SIGINT 阻塞\n");
    }

    //向信号集中加入指定的信号
    ret = sigaddset(&set,SIGINT);
     if(ret == -1){
        perror("sigaddset-SIGINT");
        exit(0);
    }

    ret = sigaddset(&set,SIGQUIT);
     if(ret == -1){
        perror("sigaddset-SIGQUIT");
        exit(0);
    }

    //判断SIGINT 是否在信号集中
     ret = sigismember(&set,SIGINT);
    if(ret == -1){
        perror("sigismember-SIGINT");
        exit(0);
    }
    else if(ret == 0){
        printf("SIGINT 不阻塞\n");
    }
    else if(ret == 1){
        printf("SIGINT 阻塞\n");
    }   

    //判断SIGQUIT 是否在信号集中
    ret = sigismember(&set,SIGQUIT);
    if(ret == -1){
        perror("sigismember-SIGQUIT");
        exit(0);
    }
    else if(ret == 0){
        printf("SIGQUIT 不阻塞\n");
    }
    else if(ret == 1){
        printf("SIGQUIT 阻塞\n");
    }   
    //删除一个信号

    ret = sigdelset(&set,SIGQUIT);
     if(ret == -1){
        perror("sigdelset-SIGQUIT");
        exit(0);
    }

     //删完后判断下 SIGQUIT 是否在信号集中
    ret = sigismember(&set,SIGQUIT);
    if(ret == -1){
        perror("sigismember-SIGQUIT");
        exit(0);
    }
    else if(ret == 0){
        printf("SIGQUIT 不阻塞\n");
    }
    else if(ret == 1){
        printf("SIGQUIT 阻塞\n");
    }   
    return 0;
}

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值