【Linux】信号集及相关函数(sigemptyset、sigfillset、sigprocmask)

news2025/1/12 5:02:11

目录

  • 1、信号集
  • 2、自定义信号集相关函数
  • 3、sigprocmask函数
      • 函数解析
      • 代码举例

橙色

1、信号集

  • 多个信号组成的一个集合称为信号集,其系统数据类型为 sigset_t 。

  • 在 PCB 中有两个非常重要的信号集,一个称为“阻塞信号集”,另一个是“未决信号集”。信号产生但是没有被处理 (未决),在内核中将所有的没有被处理的信号存储在一个集合中 (未决信号集)。这个未决状态的信号,需要被处理,处理之前需要和另一个信号集(阻塞信号集),进行比较,在处理的时候和阻塞信号集中的标志位进行查询,看是不是对该信号设置阻塞了。

  • 信号的“未决”是一种状态,指的是从信号的产生到信号被处理前的这一段时间。

  • 信号的“阻塞”是一个开关动作,指的是阻止信号被处理,但不是阻止信号产生。

  • 信号的阻塞就是让系统暂时保留信号留待以后发送。由于另外有办法让系统忽略信号.所以一般情况下信号的阻塞只是暂时的,只是为了防止信号打断敏感的操作。

2、自定义信号集相关函数

以下信号集相关的函数都是对自定义的信号集进行操作

/*

    int sigemptyset(sigset_t *set);
        - 功能:清空信号集中的数据,将信号集中的所有的标志位置为0
        - 参数:set,传出参数,需要操作的信号集
        - 返回值:成功返回0, 失败返回-1

    int sigfillset(sigset_t *set);
        - 功能:将信号集中的所有的标志位置为1
        - 参数:set,传出参数,需要操作的信号集
        - 返回值:成功返回0, 失败返回-1

    int sigaddset(sigset_t *set, int signum);
        - 功能:设置信号集中的某一个信号对应的标志位为1,表示阻塞这个信号
        - 参数:
            - set:传出参数,需要操作的信号集
            - signum:需要设置阻塞的那个信号
        - 返回值:成功返回0, 失败返回-1

    int sigdelset(sigset_t *set, int signum);
        - 功能:设置信号集中的某一个信号对应的标志位为0,表示不阻塞这个信号
        - 参数:
            - set:传出参数,需要操作的信号集
            - signum:需要设置不阻塞的那个信号
        - 返回值:成功返回0, 失败返回-1

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

*/

代码举例

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

int main() {

    // 创建一个信号集,一开始可能有某些标志位为1,所以下一步需要清空
    sigset_t set;

    // 清空信号集的内容
    sigemptyset(&set);

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

    // 添加几个信号到信号集中
    sigaddset(&set, SIGINT);
    sigaddset(&set, SIGQUIT);

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

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

    // 从信号集中删除一个信号
    sigdelset(&set, SIGQUIT);

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

    return 0;
}

在这里插入图片描述

3、sigprocmask函数

函数解析

/*
    int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
        - 功能:将自定义信号集中的数据设置到内核中(设置阻塞,解除阻塞,替换)
        - 参数:
            - how : 如何对内核阻塞信号集进行处理
                SIG_BLOCK: 将用户设置的阻塞信号集添加到内核中,内核中原来的数据不变
                    假设内核中默认的阻塞信号集是mask, mask | set
                SIG_UNBLOCK: 根据用户设置的数据,对内核中的数据进行解除阻塞
                    mask &= ~set(也就是先对set取反,再与mask按位与),假设内核中默认的阻塞信号集是mask
                SIG_SETMASK:覆盖内核中原来的值
            
            - set :已经初始化好的用户自定义的信号集
            - oldset : 保存设置之前的内核中的阻塞信号集的状态,可以是 NULL
        - 返回值:
            成功:0
            失败:-1
                设置错误号:EFAULT、EINVAL

    int sigpending(sigset_t *set);
        - 功能:获取内核中的未决信号集
        - 参数:set,传出参数,保存的是内核中的未决信号集中的信息。
*/

代码举例

该代码首先自定义了信号集 set,并把 SIGINT 和 SIGQUIT 信号放入其中。然后又通过 sigprocmask 函数修改了内核中的阻塞信号集。接着设置了死循环,在循环内创建了一个信号集pendingset,并将当前的未决信号集的数据放入pendingset,接着遍历该信号集的前31位。

当你运行该程序时,首先输出的都会是0,接着在循环10次之前,按ctrl+c,打印出的第二位就会从0变成1(其实也就是你按ctrl+c的时候,就代表向系统发送 SIGINT 信号,但该信号通过上面的操作在内核中的阻塞信号集中已经被设置为1了,所以当系统接收到该信号时,也就会阻塞,因此该信号状态为未决,打印出的未决信号集的第二位(代表SIGINT)也就变为了1)。

10次循环之后,解除了阻塞。之前按ctrl+c也没办法停止死循环,但按完ctrl+c且10次循环之后,死循环就会自动停止,因为程序设置10次之后解除我们之前设置的信号阻塞,此时系统不再阻塞之前所发送的SIGINT 信号,于是SIGINT 信号发挥自己的作用,停止了该进程。

// 编写一个程序,把所有的常规信号(1-31)的未决状态打印到屏幕
// 设置某些信号是阻塞的,通过键盘产生这些信号

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

int main() {

    // 设置2、3号信号阻塞
    sigset_t set;
    sigemptyset(&set);
    // 将2号和3号信号添加到信号集中
    sigaddset(&set, SIGINT);
    sigaddset(&set, SIGQUIT);

    // 修改内核中的阻塞信号集
    sigprocmask(SIG_BLOCK, &set, NULL);

    int num = 0;

    while(1) {
        num++;
        // 获取当前的未决信号集的数据
        sigset_t pendingset;
        sigemptyset(&pendingset);
        sigpending(&pendingset);

        // 遍历前32位
        for(int i = 1; i <= 31; i++) {
            if(sigismember(&pendingset, i) == 1) {
                printf("1");
            }else if(sigismember(&pendingset, i) == 0) {
                printf("0");
            }else {
                perror("sigismember");
                exit(0);
            }
        }

        printf("\n");
        sleep(1);
        if(num == 10) {
            // 解除阻塞
            sigprocmask(SIG_UNBLOCK, &set, NULL);
        }

    }

    return 0;
} 

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/558332.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Charles 抓包工具下载安装及基础使用

在Charles抓包工具之前讲过了Fiddler抓包工具&#xff0c;在讲之前先来解决读者的该怎么读这两个单词&#xff08; Charles 读&#xff1a;雀奥斯 和 Fiddler 读&#xff1a;非的了 &#xff09;&#xff0c;下面进入正题&#xff0c;有使用过抓包工具的或者看过之前关于Fiddle…

leecode530—二叉搜索树的最小绝对差

leecode530 二叉搜索树的最小绝对差 &#x1f50e;首先要知道二叉搜索树是有序的&#xff0c;补充一下二叉搜索树的相关概念。 &#x1f7e0; 对于 BST 的每一个节点 node&#xff0c;左子树节点的值都比 node 的值要小&#xff0c;右子树节点的值都比 node 的值大。 &#x1f…

数据分析笔记:基本概念,常用图表,报告大纲

1.数据分析 1.1定义 对数据进行分析。数据分析是为了提取有用信息和形成结论而对数据加以详细研究和概括总结的过程。在实际工作中&#xff0c;帮助管理者判断和决策。 1.2步骤 数据分析的基本步骤包括明确思路&#xff0c;制定计划、数据收集、数据处理、数据分析、数据显…

chatgpt赋能Python-python_kanren

Python Kanren&#xff1a;一种强大的逻辑编程工具 Python Kanren是一种基于Python的逻辑编程工具&#xff0c;它可以帮助开发人员轻松地构建复杂的逻辑应用程序。如果您正在寻找一种可以帮助您更快地开发和测试逻辑代码的工具&#xff0c;那么Python Kanren绝对是一个不错的选…

MySQL 用户管理

目录 用户管理 用户 用户信息 创建用户 删除用户 修改用户密码 数据库的权限 给用户 注意&#xff1a;如果发现赋权限后&#xff0c;没有生效&#xff0c;执行如下指令&#xff1a; 回收权限 用户管理 如果我们只能使用 root 用户&#xff0c;这样存在安全隐患。这时…

有没有高清录制视频软件?如何录制清晰的视频?

案例&#xff1a;录屏画质模糊影响观看怎么办&#xff1f; 【我把我在电脑上的操作录制了下来&#xff0c;录屏虽然可以看清楚操作的步骤&#xff0c;但是画质比较模糊&#xff0c;看起来很不舒服。有没有什么方法可以录制清晰画质的视频&#xff1f;】 当今数字化时代&#…

Ubutun安装Anconda3

一、下载Anconda 方法一&#xff1a;官网下载 https://www.anaconda.com/download&#xff08;比较费时&#xff09; 可以点击右键复制地址 使用Wget下载 wget https://repo.anaconda.com/archive/Anaconda3-2023.03-1-Linux-x86_64.sh方法 2&#xff1a;清华源 在清华大…

Shell运维实战2-条件判断与函数

目录 Shell 条件测试与比较脚本条件测试文本测试表达式字符串测试表达式整数二元比较操作符逻辑操作符区别总结 if 语句Shell 函数基础执行 Shell 条件测试与比较 脚本条件测试 # -f判断文件是否存在&#xff0c;如果存在返回真&#xff0c;反之为假 # 一下结构类似于三元运算…

Hadoop基础学习---5、MapReduce概述和WordCount实操(本地运行和集群运行)、Hadoop序列化

1、MapReduce概述 1.1 MapReduce定义 MapReduce是一个分布式运算程序的编程框架&#xff0c;是用户开发“基于Hadoop的数据分析应用”的核心框架。 MapReduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序&#xff0c;并发运行在一个Had…

如何在宝塔面板后的阿里云服务器运行Flask项目并公网可以访问?

在你的服务器安装宝塔面板 宝塔面板是服务器运维管理系统 使用宝塔前&#xff1a; 手工输入命令安装各类软件&#xff0c;操作起来费时费力并且容易出错&#xff0c;而且需要记住很多Linux的命令&#xff0c;非常复杂。 使用宝塔后&#xff1a; 2分钟装好面板&#xff0c;一键…

二维码在中国:学术视角下的创新与实践

相关统计数据显示&#xff0c;全球每天要扫100亿个二维码&#xff0c;而中国的二维码应用占到全球九成左右&#xff0c;平均每人每天扫码6次以上。 作为万物互联时代的“数字身份证”&#xff0c;二维码在物流运输、生产制造、会议签到、移动支付、餐饮服务、资产管理、市场营…

活动在线制作投票链接如果制作投票链接线上投票链接制作

近些年来&#xff0c;第三方的微信投票制作平台如雨后春笋般络绎不绝。随着手机的互联网的发展及微信开放平台各项基于手机能力的开放&#xff0c;更多人选择微信投票小程序平台&#xff0c;因为它有非常大的优势。 1.它比起微信公众号自带的投票系统、传统的H5投票系统有可以图…

简单分享在微信上社区团购小程序制作步骤

打造属于自身的独立小程序拥有更高的自主性&#xff0c;特别是基于得店小程序的创新产品力&#xff0c;从设计上彰显品牌理念&#xff0c;到功能上进行扩展拓宽营销方式&#xff0c;都完全自我掌控&#xff0c; ● 更重要的是&#xff0c;相比于平台上各种复杂的机制&#xff0…

chatgpt赋能Python-python_headers

什么是Python Headers&#xff1f; Python Headers是Python程序的一部分&#xff0c;它负责导入Python模块和库。这些头文件包含有关Python模块和库的信息&#xff0c;它们允许程序员编写Python扩展并将它们与Python解释器连接&#xff0c;使其能够正确运行。 Python Headers…

Linkage Mapper Toolkit中的Pinchpoint Mapper功能解析(含实例分析)

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: Linkage Mapper解密数字世界链接 白尾兔(Lepus townsendii)的Pinchpoint映射器输出和栖息地浓集区效果图: 图片来源地址 <

Fourier分析入门——第6章——连续函数的Fourier分析

目录 第 6 章 连续函数的Fourier分析 6.1 引言 6.2 Fourier模型 6.3 求取Fourier系数的实用方法 6.4 相关定理 6.4.1 线性定理(linearity) 6.4.2 平移定理(Shift theorem) 6.4.3 伸缩定理(Scaling theorem) 6.4.4 微分定理(Differentiation theorem) 6.4.5 积分定理…

【初识C语言】数组

【初识C语言】数组 一.一维数组1.什么是数组1.一维数组的创建和初始化1.数组如何创建2.数组如何初始化3.用sizeof来求数组的长度 2.一维数组的使用3.一维数组在内存中的存储方式 二. 二维数组1,什么是二维数组2.二维数组的创建3.二维数组的初始化4.二维数组的使用5.二维数组在内…

GD32F4x 加密(开启读保护功能)

参考链接1&#xff1a;&#xff08;设置读保护&#xff09; GD32F4x 如何开启读保护功能&#xff08;芯片加密&#xff09;&#xff1f;_EmbeddedOsprey的博客-CSDN博客 参考链接2&#xff1a;读取芯片ID进行加密 《嵌入式 – GD32开发实战指南》第19章 程序加密_gd32大小端…

A-4D战斗机姿态控制的模型预测控制方法(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 飞行器姿态控制通过复杂的动力学来描述&#xff0c;这使得该系统的控制算法的设计变得困难。除此之外&#xff0c;战斗机尤其被设…

[230531] 托福听力真题|TPO67配套词汇|10:23-11:23

目录 Con1 Lec1(ecology) Lec2(psychology) Con2 Lec3(art history) 重点复习巩固lecture 两篇Con都为简单等级 Con1 emergency n 紧急情况&#xff1b;突发情况 deal with 处理 dormitory n 宿舍 facility n 设备 supervisor n 监督…