当前位置: 首页 > article >正文

信号集操作函数

控制原理:内核通过读取未决信号集来判断信号是否应被处理。信号屏蔽字mask可以影响未决信号集。而我们可以在应用程序中自定义set来改变mask。已达到屏蔽指定信号的目的。

更多函数具体使用 man *** 的方式查看手册 

信号集操作函数使用原理分析https://www.bilibili.com/video/BV1KE411q7ee/?p=134&spm_id_from=pageDriver&vd_source=d239c7cf48aa4f74eccfa736c3122e65

 信号集设定

sigset_t  set;                   

                                自定义信号集                        // typedef unsigned long sigset_t;

int sigemptyset(sigset_t *set);         

                                将某个信号集清0                        成功:0;失败:-1

int sigfillset(sigset_t *set);               

                                 将某个信号集置1                        成功:0;失败:-1

int sigaddset(sigset_t *set, int signum);         

                                将某个信号加入信号集                成功:0;     失败:-1

int sigdelset(sigset_t *set, int signum);           

                                将某个信号清出信号集                成功:0;失败:-1

int sigismember(const sigset_t *set, int signum);

                                判断某个信号是否在信号集中 

                                返回值:在集合:1;不在:0;出错:-1 

sigset_t类型的本质是位图。

                但不应该直接使用位操作,而应该使用上述函数,保证跨系统操作有效。

设置信号屏蔽字和解除信号屏蔽字

用来屏蔽信号解除屏蔽也使用该函数。其本质,读取或修改进程的信号屏蔽字(PCB 中)

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

        成功:0;失败:-1,设置 errno

        参数:

                set:自定义 set

                         传入参数,是一个位图,set中哪位置1,就表示当前进程屏蔽哪个信

                oldset:旧有的 mask

                        传出参数,保存旧的信号屏蔽集。

                how:

                        SIG_BLOCK:                                      设置阻塞

                        SIG_UNBLOCK:                                 取消阻塞

                        SIG_SETMASK:                                 用自定义 set 替换 mask

 查看未决信号集:

        int sigpending(sigset_t *set); 

                set:传出的  未决信号集

                返回值:成功:0;失败:-1,设置errno

案例一: 屏蔽ctrl+c信号,打印未决信号集

从结果可以很清楚的看出,当我们按下ctrl+c 未决信号机2号位置变成1,并且一直保持,就是因为我们利用·sigprocmask设置了阻塞信号集,信号无法递达。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<pthread.h>
#include<signal.h>

void sys_err(const char *str)
{
    perror(str);
    exit(1);
}

void print_set(sigset_t *set) //打印操作 
{
    int i;
    for(i = 1; i < 32; i++)
    {
        if(sigismember(set, i)){ //利用成员判断函数
            putchar('1');
        } else {
            putchar('0');
        }
    }
    printf("\n");
}


int main(int argc, char *argv[])
{
    sigset_t set, oldset, pedset;

    int ret = 0;

    sigemptyset(&set);         // 清空
    sigaddset(&set, SIGINT);   //屏蔽 ctrl + c
    sigaddset(&set, SIGQUIT);  //屏蔽 ctrl + \
    sigaddset(&set, SIGBUS);   //屏蔽 总线
    sigaddset(&set, SIGKILL);  //屏蔽 kill   9号信号无法屏蔽

    //SIG_BLOCK 表示添加阻塞信号 set表示要覆盖的信号集 oldset表示旧的信号集
    ret = sigprocmask(SIG_BLOCK, &set, &oldset); //设置阻塞
    if(ret == -1){
        sys_err("sigprocmask error");
    }
    
    while(1)
    {
        ret = sigpending(&pedset);  //获取未决信号集 传出
        if(ret == -1){
            sys_err("sigpending error");
        }

         print_set(&pedset);  //打印 自定义的函数
         sleep(1);
    }

    return 0;
}


http://www.kler.cn/a/5306.html

相关文章:

  • Mac中配置vscode(第一期:python开发)
  • Selenium 的四种等待方式及使用场景
  • NRC优先级中比较特殊的—NRC0x13和NRC0x31
  • 创建Java项目,并添加MyBatis包和驱动包
  • 经典多模态模型CLIP - 直观且详尽的解释
  • AI赋能R-Meta分析核心技术:从热点挖掘到高级模型、助力高效科研与论文发表
  • Matbox V1.0.7更新预览与手册
  • TryHackMe-harder(boot2root)
  • ShaderGraph前言
  • English Learning - L2 语音作业打卡 舌边音 [r] [l] Day37 2023.3.29 周三
  • 你知道Python 最常用的 20 个包吗(按照使用频率排序)
  • Java 抽象类中构造方法的作用?如何理解?
  • JS和Jquery
  • 大屏使用dv-digital-flop定时刷新显示总人数
  • 一文实战 | RISC-V Linux入口地址2M预留内存优化
  • 如何在 Linux 上安装和使用 exa?
  • 二值mask转polygon/RLE (coco segment格式)
  • RSA解密-第十届Java研究生组E题
  • Leetcode: 236.二叉树的最近公共祖先
  • 医用超声检查设备
  • 无线耳机哪个品牌好?四大国内蓝牙耳机品牌排行
  • 软件工程导论(四)总体设计(临时)
  • 49天精通Java,第21天,Java内部类,看看文心一言、ChatGPT怎么说
  • MongoDB的优缺点以及springboot中的使用
  • TypeScript学习笔记一
  • 超级进化吧switch case in java