【Linux】信号集及信号集操作函数

文章目录

  • 一、信号集是什么?
  • 二、信号集操作函数
    • 1. sigemptyset
    • 2. sigfillset
    • 3. sigaddset
    • 4. sigdelset
    • 5. sigismember
    • 6. sigprocmask (仅用于读取或更改block表)
    • 7. sigpending (仅用于读取pending表)


一、信号集是什么?

对于每个进程, 都有三个信号集, 分别是:

  • block: 阻塞信号集
  • pending: 未决信号集
  • handler: 信号的处理函数

用 sigset_t 用来表示 block, pending 两个表的类型, 作位图使用, 0/1 分别表示无效/有效, 在 block 表中, 0 表示对应信号未收到阻塞信号, 1 表示对应信号收到阻塞信号, 在 pending 表中, 0 表示该进程未收到对应信号, 1 表示该进程收到对应信号, 在 handler 表中, 存在两种可选的宏, 分别是 SIG_DFL, SIG_IGN, 分别表示执行默认处理函数和忽略该信号, 即收到该信号后什么也不做就是处理动作.

当一个进程的 block 表中的对应信号被置为 1, 即表示该信号被阻塞了, 即使该进程收到了对应信号, 只会将其存储在 pending 表中, 并不会处理该信号, 当该信号在 block 表中被置为 0, 即解除对该信号的阻塞时, 此时如果 pending 表中对应的信号为 1, 才会在合适的时候(由内核态到用户态时)执行对应的处理函数.

其中 block, pending 表中的下标就表示相应的信号, handler 中存储的类型为 void sighandler(int signo).

二、信号集操作函数

1. sigemptyset

头文件: #include <signal.h>
函数声明: int sigemptyset(sigset_t *set);

  • 返回值: 成功返回 0, 失败返回 -1.
  • set: 被设置的集合.

功能: 将信号集(block/pending)中的二进制位都置为 0, 可用于初始化.

示例代码:

#include <iostream>
#include <signal.h>
using namespace std;int main()
{sigset_t set;sigemptyset(&set);for(int i = 1; i <= 31; ++i){cout << sigismember(&set, i) ? 1 : 0;}cout << endl;return 0;
}

运行结果:
在这里插入图片描述
可以看到该集合中的二进制位都被置为 0 了.

2. sigfillset

头文件: #include <signal.h>
函数声明: int sigfillset(sigset_t *set);

  • 返回值: 成功返回 0, 失败返回 -1.
  • set: 被设置的集合.

功能: 将信号集(block/pending)中的二进制位都置为 1.

示例代码:

#include <iostream>
#include <signal.h>
using namespace std;int main()
{sigset_t set;sigfillset(&set);for(int i = 1; i <= 31; ++i){cout << sigismember(&set, i) ? 1 : 0;}cout << endl;return 0;
}

运行功能:
在这里插入图片描述
可以看到该集合中的二进制位都被置为 1 了.

3. sigaddset

头文件: #include <signal.h>
函数声明: int sigaddset(sigset_t *set, int signum);

  • 返回值: 成功返回 0, 失败返回 -1.
  • set: 被设置的集合.
  • signum: 设置的信号

功能: 将对应信号设置到信号集(block/pending)中, 对应信号的二进制位置为 1.

示例代码:

#include <iostream>
#include <signal.h>
using namespace std;int main()
{sigset_t set;sigemptyset(&set);sigaddset(&set, 2);for(int i = 31; i >= 1; --i){cout << sigismember(&set, i) ? 1 : 0;}cout << endl;return 0;
}![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/b0fca399c38143b49331eb6613e9223e.png)

运行结果:
在这里插入图片描述
可以看到, 对应的信号被设置进了信号集中.

4. sigdelset

头文件: #include <signal.h>
函数声明: int sigdelset(sigset_t *set, int signum);

  • 返回值: 成功返回 0, 失败返回 -1.
  • set: 被设置的集合.
  • signum: 需要删除的信号.

功能: 将对应信号从信号集(block/pending)中删除, 对应信号的二进制位置为 0.

示例代码:

#include <iostream>
#include <signal.h>
using namespace std;int main()
{sigset_t set;sigfillset(&set);sigdelset(&set, 2);for(int i = 31; i >= 1; --i){cout << sigismember(&set, i) ? 1 : 0;}cout << endl;return 0;
}

运行结果:
在这里插入图片描述
可以看到信号集中对应信号的 1 被置为了 0.

5. sigismember

头文件: #include <signal.h>
函数声明: int sigismember(const sigset_t *set, int signum);

  • 返回值: 如果 signum 信号在 set 中为 1, 则返回 1, 为 0, 则返回 0, 调用失败返回 -1.
  • set: 被检测的集合.
  • signum: 被检测的信号.

功能: 检测信号集中是否收到对应信号.

示例代码:

#include <iostream>
#include <signal.h>
using namespace std;int main()
{sigset_t set;sigemptyset(&set);sigaddset(&set, 2);for(int i = 31; i >= 1; --i){cout << sigismember(&set, i) ? 1 : 0;}cout << endl;return 0;
}

运行结果:
在这里插入图片描述
在代码中, 先对信号集进行初始化, 在将 2 号信号设置进信号集中, 此时通过 sigismember 函数遍历判断信号集收到了哪些信号.

6. sigprocmask (仅用于读取或更改block表)

头文件: #include <signal.h>
函数声明: int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

  • 返回值: 成功返回 0, 失败返回 -1.
  • how: 如何更改进程的 block 表.
  • set: 将 set 信号集的内容设置给进程的 block 表.
  • oldset: 输出型参数, 将调用进程老的 block 表中的内容保存到 oldset 中.

功能: 函数 1 - 5 只是对 sigset_t 类型的变量进行操作, 通过 sigprocmask 函数才能将 sigset_t 类型的变量设置进调用进程的 block 表中.

how 参数可选值:

  • SIG_BLOCK: 将参数 set 中的阻塞信号添加到调用进程的 block 表中, 相当于 mask |= set, 追加式添加阻塞信号.
  • SIG_UNBLOCK: 将参数 set 中的阻塞信号从调用进程的 block 表中解除, 相当于 mask = mask & (~set).
  • SIG_SETMASK: 将调用进程的 block 表设置为 set, 相当于 mask = set, 覆盖式添加阻塞信号.

在 Linux 中, how 的三个参数其实也就是宏:

/* Values for the HOW argument to `sigprocmask'.  */
#define	SIG_BLOCK     0		 /* Block signals.  */
#define	SIG_UNBLOCK   1		 /* Unblock signals.  */
#define	SIG_SETMASK   2		 /* Set the set of blocked signals.  */

示例代码:

#include <iostream>
#include <signal.h>
#include <unistd.h>
using namespace std;int main()
{sigset_t set;sigset_t old_set;sigemptyset(&set);sigemptyset(&old_set);sigaddset(&set, 2);sigprocmask(SIG_SETMASK, &set, &old_set);while(1){for(int i = 31; i >= 1; --i){cout << sigismember(&set, i) ? 1 : 0;}cout << endl;sleep(1);}return 0;
}

运行结果:
在这里插入图片描述
首先将 2 号信号添加到信号集变量 set 中, 通过 SIG_SETMASK 的方式将 set 中设置的阻塞信号添加到调用进程的阻塞信号集中, 在此之前, 先将调用进程原本的阻塞信号集中的内容添加给 old_set, 而后调用进程的阻塞信号集才会被 set 覆盖, 第三个参数也可以置为 nullptr, 表示不接收调用进程原本的阻塞信号集, 通过运行结果可以直观的看出, 在 2 号信号被阻塞后, 我们在终端输入 Ctrl + C 后就无效了.

7. sigpending (仅用于读取pending表)

头文件: #include <signal.h>
函数声明: int sigpending(sigset_t *set);

  • 返回值: 成功返回 0, 失败返回 -1.
  • set: 输出型参数, 将调用进程的 pending 表设置进 set.

功能: 获取调用进程的 pending 表.

示例代码:

#include <iostream>
#include <signal.h>
using namespace std;int main()
{sigset_t set;sigpending(&set);for(int i = 31; i >= 1; --i){cout << sigismember(&set, i);fflush(stdout);}cout << endl;return 0;
}

运行结果:
在这里插入图片描述
调用进程没有收到任何信号, 所以 pending 表全为 0.

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

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

相关文章

k8s集群部署成功后某个节点突然出现notready状态解决办法

通过&#xff1a; kubectl get nodes 查看master1节点为not ready 通过查看日志&#xff1a; journalctl -f -u kubelet.service 看到这里 查看状态&#xff1a; systemctl status kubelet.service 重启一样会报错 执行&#xff1a; swapoff -a 执行后&#xff0c;重启…

pytorch深度学习-环境搭建

1.Anaconda下载&#xff08;首先安装Anaconda不需要先安装Python了&#xff01;&#xff09; 版本 3.11. Download Anaconda Distribution | Anaconda 1.2 跳过注册直接下载 2.安装 直接next, (Install for 可以选择All Users&#xff0c;我选择的是All Users) 点击默认选项…

Qt Designer 使用笔记

目录 qt designer安装 预览 Ctrl R 使用 Qt Designer 设计的ui文件可以通过以下命令转为.py文件 命令行脚本&#xff1a; pycharm工具栏配置&#xff1b; pyqt5也是可以的&#xff1a; 2.2 测试是否配置成功 设置背景颜色&#xff1a; ui收集 qt designer安装 pip ins…

高耗能工厂实现ESG能源管控的策略与实践探讨-天拓四方

随着全球气候变化的加剧和ESG&#xff08;环境、社会和治理&#xff09;理念的普及&#xff0c;高耗能工厂面临着巨大的挑战和机遇。如何有效地实现ESG能源管控&#xff0c;不仅关乎企业的可持续发展&#xff0c;也是应对全球环境问题的关键一环。本文将探讨高耗能工厂实现ESG能…

JavaEE-网络初识

文章目录 一、网络背景1.1 起源1.2 国内网络的发展 二、关键概念2.1 网络2.2 设备2.3 ip地址与端口号 三、协议3.1 协议分层3.2 OSI七层模型3.3 TCP/IP五层模型3.4 数据传输过程的简单叙述 一、网络背景 1.1 起源 在国外大概时上世纪70年代左右&#xff0c;网络就出现了&…

U-Mail邮件系统取得多项适配认证,全面支持国产化信创环境

随着信息技术的发展&#xff0c;信息化建设越来越深入到社会各个领域&#xff0c;成为驱动经济社会发展的重要力量。在此背景下&#xff0c;我国正加快构建国家信息安全保障体系&#xff0c;实现自主可控&#xff0c;形成安全可靠的信息技术体系。这正是我们所说的“信创”&…

Linux中经典的并发编程问题生产者和消费者

一&#xff0c;进程和线程区别 1&#xff0c;进程是程序的一次执行实例&#xff0c;是系统进行资源分配和调度的独立单位。进程具有独立的内存空间、系统资源以及独立的执行序列。每个进程都有其独立的进程控制块&#xff08;PCB&#xff09;&#xff0c;用于描述进程的状态和…

Flutter 中的 TabBarView 小部件:全面指南

Flutter 中的 TabBarView 小部件&#xff1a;全面指南 在Flutter中&#xff0c;TabBarView是一个用于创建选项卡式界面的小部件&#xff0c;它与TabController一起使用&#xff0c;可以构建复杂的选项卡导航界面。本文将为您提供一个全面的指南&#xff0c;帮助您了解如何使用…

ssl证书价格一年多少钱?怎么申请?

随着各大平台下架了一年期免费证书&#xff0c;免费证书的有效期都为90天。更多企业选择付费证书。费用是众多用户关心的话题&#xff0c;一年期SSL证书价格在几十到几千元不等。 一年期SSL证书价格查看https://www.joyssl.com/certificate/select/0-1000.html?nid16 下面是…

如何官方查询论文分区,中科院及JCR

中科院分区 有一个小程序&#xff1a;中科院文献情报中心分区表 点2023升级版&#xff0c;输入期刊名 大类1区 JCR分区 进入官方网站 Journal Citation Reports 输入要查询的期刊名&#xff0c;点开 拼命往下拉 这就是根据影响因子的排名&#xff0c;在computer science&am…

农业场景下的slam论文汇总

文章目录 概述2020Ground-Level Mapping and Navigating for Agriculture Based on IoT and Computer VisionCanopy Density Estimation in Perennial Horticulture Crops Using 3D Spinning Lidar SLAM 2021Mobile 3D scan LiDAR: a literature reviewSLAM in the Field: An E…

华为欧拉 openEuler 22.03 LTS SP3 一键安装 Oracle 21C RAC

前言 Oracle 一键安装脚本&#xff0c;演示 openEuler 22.03 LTS SP3 一键安装 Oracle 21C RAC 过程&#xff08;全程无需人工干预&#xff09;。 ⭐️ 脚本下载地址&#xff1a;Shell脚本安装Oracle数据库 安装准备 1、安装好操作系统&#xff0c;建议安装图形化2、配置好网…

git版本回退

代码推送到远程仓库之后想回退并且不保留任何历史记录&#xff1a; 查看版本号信息git log&#xff1a; git log commit version_example1 (HEAD -> dev, origin/dev, origin/HEAD) Author: xxx <email> Date: xxxXXX注释commit version_example2 Author: xxx <…

【Linux】在内网环境通过代理使用公网Docker镜像

一般来说&#xff0c;软件公司的开发环境多位于内网中&#xff0c;在容器的使用上会使用内部镜像源。但是&#xff0c;内部软件源上的镜像总是不那么丰富&#xff0c;如果想使用公网镜像&#xff0c;该怎么办&#xff1f; 文章目录 1、确定有一台可访问公网的机器2、在该机器上…

Unity 读取本地xml出现的问题

当时遇到的第一个问题是&#xff0c;想要有个读取xml的方法&#xff0c;写在了Ienumerator里面的。所以需要等待文本读写完毕&#xff0c;获得文本的数据&#xff0c;才能执行下一步的代码。 解决办法&#xff1a;在方法执行到最后的时候&#xff0c;增加回调函数。 还有一个…

flutter webview加载本地文件出现跨域解决方案

一直报错 [INFO:CONSOLE(17)] "Access to image at file:///android_asset/flutter_assets/assets/jump/box_bottom.png from origin null has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome…

对话阿里云云原生产品负责人李国强:推进可观测产品与OpenTelemetry开源生态全面融合

5 月 22 日&#xff0c;在最新一期的飞天发布时刻上&#xff0c;阿里云宣布多款可观测产品全面升级&#xff0c;其中一项是应用实时监控服务 ARMS 在业内率先推进了与 OpenTelemetry 开源生态的全面融合&#xff0c;极大丰富了可观测的数据类型及规模&#xff0c;大幅增强了 AR…

带你玩转OpenHarmony AI:打造智能语音子系统

简介 AI时代&#xff0c;智者当先&#xff0c;判断一个终端设备是否智能&#xff0c;语音能力是必不可缺的。智能家居、智慧厨房、智能汽车等等&#xff0c;一切衣食住行都在往智能方向发展&#xff0c;那我们该如何在OpenAtom OpenHarmony&#xff08;简称“OpenHarmony”&am…

使用Java Stream API的map方法将包含Long类型ID的流转换为String数组

在这个例子中&#xff0c;idList是一个包含Long类型ID的列表。我们使用stream()方法创建一个流&#xff0c;然后应用map(String::valueOf)方法将Long类型的ID转换为String类型。最后&#xff0c;我们使用toArray(String[]::new)方法将流中的元素收集到一个新的String[]数组中。…

【spark001】SparkSQL内置函数手册总结(更新中)

1.熟悉、梳理、总结下SparkSQL相关知识体系。 2.日常研发过程中使用较少&#xff0c;随着时间的推移&#xff0c;很快就忘得一干二净&#xff0c;所以梳理总结下&#xff0c;以备日常使用参考 3.欢迎批评指正&#xff0c;跪谢一键三连&#xff01; 文章目录 1.函数清单 1.函数清…