【LinuxC语言】信号集与sigprocmask

文章目录

  • 前言
  • 一、信号集
    • 1.1 操作信号集相关的函数
    • 1.2 信号屏蔽字
    • 1.3 sigprocmask
    • 1.4 示例代码
  • 总结


前言

在Linux C编程中,信号是一种重要的进程间通信机制,用于通知进程发生了特定的事件。然而,程序在执行过程中可能会收到各种各样的信号,有些信号可能会在不合适的时候打断程序的正常执行,造成不可预料的后果。为了控制信号的接收和处理,Linux提供了信号集和sigprocmask()函数。信号集是一种数据结构,用于管理信号的集合,而sigprocmask()函数则允许程序员临时修改进程的信号屏蔽字,以控制信号的接收和处理。


一、信号集

1.1 操作信号集相关的函数

以下是Linux C编程中用于操作信号集的函数原型,以及它们的作用、参数和返回值:

  1. int sigemptyset(sigset_t *set);

    • 作用:清空信号集,将所有信号从信号集中移除。
    • 参数set - 指向要清空的信号集的指针。
    • 返回值:成功返回0,失败返回-1,并设置errno。
  2. int sigfillset(sigset_t *set);

    • 作用:将所有信号添加到信号集中,填满信号集。
    • 参数set - 指向要填满的信号集的指针。
    • 返回值:成功返回0,失败返回-1,并设置errno。
  3. int sigaddset(sigset_t *set, int signum);

    • 作用:将指定的信号添加到信号集中。
    • 参数set - 指向要修改的信号集的指针;signum - 要添加的信号编号。
    • 返回值:成功返回0,失败返回-1,并设置errno。
  4. int sigdelset(sigset_t *set, int signum);

    • 作用:将指定的信号从信号集中移除。
    • 参数set - 指向要修改的信号集的指针;signum - 要移除的信号编号。
    • 返回值:成功返回0,失败返回-1,并设置errno。
  5. int sigismember(const sigset_t *set, int signum);

    • 作用:检查指定的信号是否在信号集中。
    • 参数set - 指向要检查的信号集的指针;signum - 要检查的信号编号。
    • 返回值:若信号在集合中则返回1,否则返回0。

这些函数提供了对信号集的基本操作,允许程序员创建、修改和检查信号集,以便有效地管理信号。通过使用这些函数,可以更方便地控制进程的信号处理行为,从而增强程序的稳定性和可靠性。

1.2 信号屏蔽字

信号屏蔽字是一个位掩码,用于指定哪些信号在进程中被阻塞,哪些信号被解除阻塞。在Linux和类Unix系统中,每个进程都有一个信号屏蔽字,它是一个用于表示信号状态的数据结构。

信号屏蔽字中的每一位对应一个特定的信号,当某一位被置为1时,表示对应的信号被阻塞;当某一位被置为0时,表示对应的信号不被阻塞,可以传递给进程。

通过设置信号屏蔽字,进程可以控制在特定的代码段中屏蔽或解除阻塞特定的信号,以确保在关键的代码段执行期间不会被某些信号中断。这对于确保程序的一致性和可靠性非常重要,特别是在需要执行临界区代码时,可以暂时阻塞某些信号,以防止它们中断关键操作。

信号屏蔽字可以通过 sigprocmask() 函数来设置和修改。此外,进程的初始信号屏蔽字通常是空的,即不阻塞任何信号,但可以通过 sigprocmask() 函数来进行初始化。

想象一下你正在玩一个游戏,但是你需要在游戏中专心地完成一个任务,比如通过一个难关。这时候,你可能不想被其他人打扰,因为那样会分散你的注意力,导致任务失败。

信号屏蔽字就像是你在游戏中设置的“专注模式”。当你打开这个模式时,其他人发送的消息不会打扰你,你可以专心地完成任务。但一旦任务完成,你可以关闭“专注模式”,再接收其他人的消息。

在编程中,信号屏蔽字的作用类似:它让程序可以在特定的时候屏蔽某些信号,不被它们打断,以便程序能够专心地执行关键的任务。这样可以确保程序在需要集中注意力时不受外界的干扰,从而提高程序的可靠性和稳定性。

1.3 sigprocmask

作用:

sigprocmask() 函数用于检索和修改进程的信号屏蔽字,即用来设置哪些信号在调用该函数期间被阻塞,哪些信号被解除阻塞。

参数:

  • how:指定如何修改信号屏蔽字的方式,有三种可能的值:
    • SIG_BLOCK:将 set 中的信号添加到当前的信号屏蔽字中。
    • SIG_UNBLOCK:从当前的信号屏蔽字中移除 set 中的信号。
    • SIG_SETMASK:用 set 中的信号替换当前的信号屏蔽字。
  • set:指向要修改的信号集的指针,根据 how 参数的不同,这个信号集有不同的含义。如果为 SIG_BLOCKSIG_UNBLOCK,则表示要添加或移除的信号集;如果为 SIG_SETMASK,则表示要替换为的新信号集。
  • oldset:指向用于存储之前信号屏蔽字的指针。如果不需要此值,可以传入 NULL

返回值:

  • 若函数调用成功,返回0;
  • 若出现错误,返回-1,并设置 errno 表示错误类型。

sigprocmask() 的作用在于允许进程控制对信号的响应时间,可以通过设置信号屏蔽字来临时阻塞或解除阻塞特定的信号,从而保证在关键代码段的执行期间不会被某些信号中断。

1.4 示例代码

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

void signal_handler(int signum) {
    printf("Received signal %d\n", signum);
}

int main() {
    // 安装信号处理程序
    signal(SIGINT, signal_handler); // 当接收到 SIGINT 信号时调用 signal_handler

    sigset_t new_mask, old_mask;

    // 初始化一个空的信号集
    sigemptyset(&new_mask);

    // 将 SIGINT 信号添加到新的信号集中
    sigaddset(&new_mask, SIGINT);

    // 设置新的信号屏蔽字
    if (sigprocmask(SIG_BLOCK, &new_mask, &old_mask) < 0) {
        perror("sigprocmask");
        exit(EXIT_FAILURE);
    }

    printf("SIGINT is blocked, press Ctrl+C to send SIGINT\n");
    sleep(5); // 等待5秒钟,此时 SIGINT 信号被阻塞

    // 解除对 SIGINT 信号的屏蔽
    if (sigprocmask(SIG_UNBLOCK, &new_mask, NULL) < 0) {
        perror("sigprocmask");
        exit(EXIT_FAILURE);
    }

    printf("SIGINT is unblocked, now you can send SIGINT\n");

    // 进入一个无限循环,等待信号的到来
    while (1) {
        sleep(1);
    }

    return 0;
}

在这里插入图片描述


总结

本文介绍了Linux C编程中的信号集与sigprocmask()函数。信号集是一种用于管理信号的集合的数据结构,程序员可以使用一系列函数来创建、修改和查询信号集,从而控制对信号的处理。而sigprocmask()函数则提供了一种临时性的控制机制,允许程序员修改进程的信号屏蔽字,以阻塞或解除阻塞特定的信号,从而控制信号的接收和处理时机。通过合理地使用信号集和sigprocmask()函数,程序员可以编写出更加健壮和可靠的信号处理程序,提高程序的稳定性和可维护性。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

银河麒麟桌面版开机后网络无法自动链接 麒麟系统开机没有连接ens33

1.每次虚拟机开机启动麒麟操作系统&#xff0c;都要输入账号&#xff0c;密码。 进入点击这个ens33 内网才连接 2. 如何开机就脸上呢&#xff1f; 2.1. 进入 cd /etc/sysconfig/network-scripts 2.2 修改参数 onbootyes 改为yes 2.3 重启即可 a. 直接重启机器查看是否正常&…

软件工程习题答案2024最新版

习题一答案 一、选择题 软件的主要特性是(A B C)。 A) **无形 **B) 高成本 C) **包括程序和文档 ** D) 可独立构成计算机系统 软件工程三要素是(B)。 A) 技术、方法和工具 B) 方法、工具和过程 C) 方法、对象和类 D) 过程、模型、方法 包含风险分析的软件工程模型是(A)…

Reactor模型详解

目录 1.概述 2.Single Reactor 3.muduo库的Multiple Reactors模型如下 1.概述 维基百科对Reactor模型的解释 The reactor design pattern is an event handling pattern for handling service requests delivered concurrently to a service handler by one or more inputs.…

【Java基础】三大特性——封装

封装 只对外提供有用的属性和行为 方法的封装 外界不会用到的方法 class MyMath {//private私有 封装函数&#xff1a;只对外提供有用的属性和行为private void toAny(int num,int base,int offSet){……}public void toHex( int num){toAny( num,15,4);}…… } class Demo…

GNU Radio创建FFT、IFFT C++ OOT块

文章目录 前言一、GNU Radio官方FFT弊端二、创建自定义的 C OOT 块1、创建 OOT 模块2、创建 OOT 块3、修改 C 和 CMAKE 文件4、编译及安装 OOT 块 三、测试1、grc 图2、运行结果①、时域波形对比②、频谱图对比 四、资源自取 前言 GNU Radio 自带的 FFT 模块使用起来不是很方便…

新型直膨式光伏光热热泵/动力热管复合循环系统

太阳能光伏光热热泵&#xff08;即PVT热泵&#xff09;技术是建筑领域内实现碳中和的有效技术手段&#xff0c;该技术具有优越的热电冷联产能力。然而&#xff0c;现有的PVT热泵在良好的室外工况下能耗较高。为了解决这一问题&#xff0c;本文提出了一种新型的DX-PVT热泵/动力热…

书接上文,助力智能化诊断高质提效,基于轻量级CNN模型MobileNet开发构建人体手骨X光骨骼骨龄分析识别系统

骨龄是骨骼年龄的简称&#xff0c;需要借助于骨骼在X光摄像中的特定图像来确定。通常要拍摄左手手腕部位的X光片&#xff0c;医生通过X光片观察来确定骨龄。这在临床上是一件非常消耗精力和时间的一项放射临床工作。写一个骨龄可能要10多分钟去完成。如果一天要写几十个骨龄&am…

10G MAC层设计系列-(4)MAC TX模块

一、前言 MAC TX模块就是要将IP层传输过来的数据封装前导码、MAC地址、帧类型以及进行CRC校验&#xff0c;并与CRC值一块组成以太网帧。 二、模块设计 首先对输入的数据进行缓存&#xff0c;原因是在之后要进行封装MAC帧头&#xff0c;所以需要控制数据流的流动 FIFO_DATA_6…

基于K8S构建Jenkins持续集成平台

文章目录 安装和配置NFSNFS简介NFS安装 在Kubernetes安装Jenkins-Master创建NFS client provisioner安装Jenkins-Master Jenkins与Kubernetes整合实现Jenkins与Kubernetes整合构建Jenkins-Slave自定义镜像 JenkinsKubernetesDocker完成微服务持续集成拉取代码&#xff0c;构建镜…

茶树(山茶属)CCoAOMT基因家族的全基因组鉴定、表达分析和蛋白质相互作用分析-全基因组家族分析-文献精读13

Genome-wide identification, expression profiling, and protein interaction analysis of the CCoAOMT gene family in the tea plant (Camellia sinensis) 茶树&#xff08;山茶属&#xff09;CCoAOMT基因家族的全基因组鉴定、表达分析和蛋白质相互作用分析&#xff0c;一篇…

详解SDRAM基本原理以及FPGA实现读写控制(一)

文章目录 一、SDRAM简介二、SDRAM存取结构以及原理2.1 BANK以及存储单元结构2.2 功能框图2.3 SDRAM速度等级以及容量计算 三、SDRAM操作命令3.1 禁止命令&#xff1a; 4b1xxx3.2 空操作命令&#xff1a;4b01113.3 激活命令&#xff1a;4b00113.4 读命令&#xff1a;4b01013.5 写…

5分钟速通大语言模型(LLM)的发展与基础知识

✍️ 作者&#xff1a;哈哥撩编程&#xff08;视频号同名&#xff09; 博客专家全国博客之星第四名超级个体COC上海社区主理人特约讲师谷歌亚马逊演讲嘉宾科技博主极星会首批签约作者 &#x1f3c6; 推荐专栏&#xff1a; &#x1f3c5; 程序员&#xff1a;职场关键角色通识宝…

【UnityRPG游戏制作】Unity_RPG项目_玩法相关

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;就业…

大语言模型教程与实践(开源)

1.简介 大语言模型&#xff08;Large Language Models, LLMs&#xff09;的兴起确实始于OpenAI在2018年发布的GPT&#xff08;Generative Pre-trained Transformer&#xff09;&#xff0c;这一开创性工作引领了自然语言处理领域的新纪元。随后&#xff0c;2022年底ChatGPT的横…

基于Spring Boot的在线BLOG网设计与实现

基于Spring Boot的在线BLOG网设计与实现 开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/idea 系统部分展示 前台首页管理界面&#xff0c;用户经过登录前台首页查看通…

SQL Server 存储过程中的字符串本身包含单引号的用法

文章目录 引言I 存储过程中的字符串本身包含单引号的用法1.1 问题1.2解决方法引言 使用场景: 字符串类型字段的值比较 I 存储过程中的字符串本身包含单引号的用法 在SQL Server中,单引号用于表示字符串常量。如果你的存储过程中的字符串本身包含单引号,你需要用两个连续的…

3.2Java全栈开发前端+后端(全栈工程师进阶之路)-前端框架VUE3框架-企业级应用- Vuex

Vuex简介 Vuex概述 Vuex是一个专门为Vue.js应用程序开发的状态管理模式, 它采用集中式存储管理所有组件的公共状态, 并以相应的规 则保证状态以一种可预测的方式发生变化. 试想这样的场景, 比如一个Vue的根实例下面有一个根组件名为App.vue, 它下面有两个子组件A.vue和B.vu…

【C++】文件

目录 文件文件分类文本文件的读写(ASCII文件)的读写打开文件打开文件的方式关闭文件将数据写入ASCII文件从ASCII文件读入数据 二进制存储对比ASCII和二进制存储用成员函数read和write读写二进制文件打开方式文件的读入与读出 文件 所谓文件&#xff0c;一般指存储在外部介质上…

【k8s】利用Kubeadm搭建k8s1.29.x版本+containerd

文章目录 前言1.准备的三台虚拟机2.安装 kubeadm 前的准备工作3.安装containerd1.解压安装包2.生成默认配置文件3.使用systemd托管containerd4.修改默认配置文件 4.安装runc5.安装 CNI plugins6.安装 kubeadm、kubelet 和 kubectl6.1 配置crictl 7.初始化集群1.打印初始化配置到…