嵌入式Linux系统编程 — 6.4 信号集

news2024/11/25 17:17:55

目录​​​​​​​

1 信号集概念

2 sigemptyset、sigfillset初始化信号集

3  sigaddset、sigdelset向信号集中添加/删除信号

4 sigismember函数测试信号是否在信号集中


1 信号集概念

在Linux系统中,信号集(signal set)用于表示一组信号的集合,信号集的使用主要涉及到信号的阻塞与未决状态的管理。很多系统调用都使用到了信号集这种数据类型来作为参数传递,譬如 sigaction()函数、 sigprocmask()函数、 sigpending()函数等。

信号集其实就是 sigset_t 类型数据结构:

# define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int)))
typedef struct
{
    unsigned long int __val[_SIGSET_NWORDS];
} sigset_t;

宏定义 _SIGSET_NWORDS:

  • 这个宏定义计算了需要多少个unsigned long int来表示所有的信号。由于Linux系统支持的信号数量最多为1024(因系统而异),每个unsigned long int的大小是其位数除以8(即字节数),再乘以sizeof(unsigned long int)得到每个unsigned long int的位数。因此,(1024 / (8 * sizeof (unsigned long int)))计算了总共需要多少个unsigned long int来存储1024个信号的位图。

sigset_t 结构体:

  • sigset_t是一个结构体,它包含一个数组类型是unsigned long int__val的数组,长度由_SIGSET_NWORDS宏定义决定。

2 sigemptyset、sigfillset初始化信号集

sigemptyset()和 sigfillset()用于初始化信号集。 sigemptyset()初始化信号集,使其不包含任何信号;而sigfillset()函数初始化信号集,使其包含所有信号(包括所有实时信号),函数原型如下:

#include <signal.h>

int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
  • set: 指向需要进行初始化的信号集变量。
  • 返回值: 成功返回 0;失败将返回-1,并设置 errno。

这两个函数通常与 sigaction(), sigpending(), sigprocmask() 等函数一起使用,以控制进程对信号的响应和处理。例如,使用 sigfillset() 可以创建一个包含所有信号的信号集,然后通过 sigprocmask() 来阻塞或允许这些信号。

下面是一个简单的使用 sigemptyset()sigfillset() 的示例:

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

int main() 
{
    sigset_t set, oldset, emptyset;

    // 填充信号集
    if (sigfillset(&set) == -1) {
        perror("Error in sigfillset");
        return 1;
    }

    // 清空信号集
    if (sigemptyset(&emptyset) == -1) {
        perror("Error in sigemptyset");
        return 1;
    }

    // 阻塞所有信号
    if (sigprocmask(SIG_BLOCK, &set, &oldset) == -1) {
        perror("Error in sigprocmask - SIG_BLOCK");
        return 1;
    }
    
    // 打印信号集状态
    printf("Current signal set is blocked.\n");

    // 恢复信号屏蔽
    if (sigprocmask(SIG_SETMASK, &oldset, NULL) == -1) {
        perror("Error in sigprocmask - SIG_SETMASK");
        return 1;
    }

    // 打印信号集状态
    printf("Original signal set restored.\n");

    return 0;
}

运行结果如下:

3  sigaddset、sigdelset向信号集中添加/删除信号

sigaddset()sigdelset() 也是用于操作信号集的函数,允许向信号集中添加或删除特定的信号,函数原型如下:

#include <signal.h>

int sigaddset(sigset_t *set, int signum);
int sigdelset(sigset_t *set, int signum);
  • set: 指向信号集。
  • signum: 需要添加/删除的信号。
  • 返回值: 成功返回 0;失败将返回-1,并设置 errno。

下面是一个简单的示例,演示如何使用 sigaddset()sigdelset()

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

int main() 
{
    sigset_t set;

    // 初始化信号集为空
    if (sigemptyset(&set) == -1) {
        perror("sigemptyset");
        return 1;
    }

    // 添加SIGINT(通常用于处理Ctrl+C中断)到信号集
    if (sigaddset(&set, SIGINT) == -1) {
        perror("sigaddset");
        return 1;
    }

    // 打印信号集状态,确认SIGINT已添加
    if (sigismember(&set, SIGINT)) {
        printf("SIGINT is in the signal set.\n");
    }

    // 从信号集中删除SIGINT
    if (sigdelset(&set, SIGINT) == -1) {
        perror("sigdelset");
        return 1;
    }

    // 再次打印信号集状态,确认SIGINT已被删除
    if (!sigismember(&set, SIGINT)) {
        printf("SIGINT is no longer in the signal set.\n");
    }

    return 0;
}

程序首先使用 sigemptyset() 创建了一个空的信号集,然后使用 sigaddset() 向信号集中添加了 SIGINT 信号,通过 sigismember() 检查 SIGINT 是否成功添加到信号集中,并打印状态信息。接着使用 sigdelset() 删除了 SIGINT 信号,并再次检查信号集状态,确认 SIGINT 已被删除。运行结果乳香

4 sigismember函数测试信号是否在信号集中

使用 sigismember()函数可以测试某一个信号是否在指定的信号集中,函数原型如下所示:

#include <signal.h>

int sigismember(const sigset_t *set, int signum);
  • set: 指定信号集。
  • signum: 需要进行测试的信号。
  • 返回值: 如果信号 signum 在信号集 set 中,则返回 1;如果不在信号集 set 中,则返回 0;失败则返回-1,并设置 errno。

以下是一个使用 sigismember() 的示例代码:

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

int main() 
{
    sigset_t set;

    // 初始化信号集,包含所有信号
    if (sigfillset(&set) == -1) {
        perror("sigfillset");
        return 1;
    }

    // 检查SIGINT是否在信号集中
    if (sigismember(&set, SIGINT)) {
        printf("SIGINT is in the signal set.\n");
    } else {
        printf("SIGINT is not in the signal set.\n");
    }

    return 0;
}

程序首先使用 sigfillset() 填充信号集 set,使其包含所有可能的信号。然后使用 sigismember() 检查 SIGINT是否是信号集的成员,并打印相应的信息。运行结果如下:

 

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

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

相关文章

优思学院|听说你想了解箱型图?教程在这里!

箱形图是什么&#xff1f; 箱形图&#xff08;也称为箱线图&#xff09;使用箱体和线条来表示一个或多个组的数值数据分布。箱体的边界表示数据中间50%的范围&#xff0c;中央线标示中位数值。线从每个箱体延伸出来&#xff0c;捕捉其余数据的范围&#xff0c;在线条之外的点表…

cadence symbol修改之一

cdaence virtuoso 复制cell&#xff0c;或者拷贝symbol之后&#xff0c;再次调用的时候&#xff0c;symbol还是跟随原来的cell名字 解决办法 打开对应的symbol 修改partName为 cellName

打造您的第一个私有智能助手

当前的大语言模型通常是基于公开的知识进行训练的&#xff0c;而我们的组织和个人用户希望能够获得有关自身私有知识的回答。为了满足这一需求&#xff0c;业界通常采用检索增强生成&#xff08;RAG&#xff09;或微调模型的方法。然而&#xff0c;这些技术对非专业人员来说门槛…

混元大模型加持,微信输入法开启AI问答新体验

在人工智能技术飞速发展的今天&#xff0c;微信作为全球最大的社交平台之一&#xff0c;一直在不断地探索和创新&#xff0c;以提供更智能、更便捷的用户体验。 最近&#xff0c;微信官方宣布了一个令人兴奋的消息&#xff1a;微信输入法正式上线了“一键AI问答”功能&#xf…

mac外接显示屏,切换程序坞和启动台在哪个屏幕显示,最实用教程

程序坞和启动项是同步的 首先&#xff0c;程序坞和展开启动项是同步出现在同一个屏幕的&#xff0c;所以只需要把程序坞“呼唤”到指定的显示器就行。 无需设置&#xff0c;动对了鼠标就行 无所谓哪个是主屏&#xff0c;设置中都没有切换程序坞位置的选项&#xff0c; 想要…

不知几DAY的Symfony---RCE复现

感谢红队大佬老流氓的供稿&#xff0c;此篇文章是针对Symfony框架的一个RCE漏洞复现 ​框架简介 Symfony是一个开源的PHP Web框架&#xff0c;它现在是许多知名 CMS 的核心组件&#xff0c;例如Drupal、Joomla!、eZPlatform&#xff08;以前称为 eZPublish&#xff09;或Bolt。…

植物大战僵尸融合版1.0下载(全部植物合体)

如果你是《植物大战僵尸》系列的忠实粉丝&#xff0c;那么有一个好消息&#xff1a;一款全新的改版游戏——《植物大战僵尸融合版》已经上线。这不仅仅是一次简单的更新&#xff0c;而是一次彻底的玩法革新。B站UP主蓝飘飘fly精心打造的这个版本&#xff0c;为玩家带来了前所未…

Java-数据结构

数据结构概述 常见的数据结构 栈 队列 数组 链表 二叉树 二叉查找树 平衡二叉树 红黑树 示例&#xff1a;

YOLO-letter box

最细致讲解yolov8模型推理完整代码--&#xff08;前处理&#xff0c;后处理&#xff09; - 博客-中国极客 (chinageek.org) 直接用resize&#xff0c;图片会变形&#xff0c;宽高比会不对 letterbox函数就是把图片弄到想要的大小&#xff0c;保持宽高比&#xff0c;然后少掉的部…

Tomcat服务部署安装

一、Tomcat基础 1.Tomcat简介 Tomcat服务器是一个免费的开放源代码的Web应用服务器&#xff0c;Tomcat虽然和Apache或者Nginx这些Web服务器一样&#xff0c;具有处理HTML页面的功能&#xff0c;然而由于其处理静态HTML的能力远不及Apache或者Nginx&#xff0c;所以Tomcat通常…

A*——AcWing 179. 八数码

A* 定义 A* 算法是一种在图形或地图中寻找最短路径的启发式搜索算法。它通过综合考虑起始节点到当前节点的实际代价和当前节点到目标节点的预估代价&#xff0c;来决定下一步的搜索方向。 运用情况 路径规划&#xff1a;如在地图导航中为车辆、行人规划最优路线。游戏开发&…

【附精彩文章合辑】佛光普照,智慧引领——记首个中文社区版Gemma-2的诞生,共筑和谐科技净土

阿弥陀佛&#xff0c;贫僧唐僧&#xff0c;自西天取经归来&#xff0c;虽已超脱尘世&#xff0c;然心系众生&#xff0c;尤是见科技日新月异&#xff0c;信息洪流浩渺无垠&#xff0c;心中不免生出几分感慨与期许。近日&#xff0c;闻讯首个中文社区版的Gemma-2即将面世&#x…

【Pyhton学习】常用标识符与关键字

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 1. 标识符与关键字2. 常用格式化输出符号3. 算数运算符4. 赋值运算符5. 比较运算符总结 1. 标识符与关键字 在Python…

桌面记笔记的软件:能加密的笔记app

在日常生活和工作中&#xff0c;很多人都有记笔记的习惯。无论是记录会议要点、学习心得&#xff0c;还是生活中的点滴灵感&#xff0c;笔记都是我们不可或缺的好帮手。然而&#xff0c;传统的纸笔记录方式逐渐不能满足现代人的需求&#xff0c;因为纸质笔记不易保存、查找困难…

动手学深度学习(Pytorch版)代码实践 -计算机视觉-39实战Kaggle比赛:狗的品种识别(ImageNet Dogs)

39实战Kaggle比赛&#xff1a;狗的品种识别&#xff08;ImageNet Dogs&#xff09; 比赛链接&#xff1a;Dog Breed Identification | Kaggle 1.导入包 import torch from torch import nn import collections import math import os import shutil import torchvision from…

nacos开启鉴权后,springboot注册失败

1.确认Nacos版本 我的Nacos版本是1.4.2 2.确认Nacos相关依赖的版本之间兼容&#xff0c;一下是我的一些pom.xml依赖 <!--父级项目的--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifa…

MySQL:MySQL总结

文章目录 MySQL思维导图基础实际在 Innodb 存储引擎中&#xff0c;会用一个特殊的记录来标识最后一条记录&#xff0c;该特殊的记录的名字叫 supremum pseudo-record &#xff0c;所以扫描第二行的时候&#xff0c;也就扫描到了这个特殊记录的时候&#xff0c;会对该主键索引加…

深化产教融合“桥梁”作用!蓝卓携手宁波4大院校共育数智人才

建强“三支队伍”赋能新质生产力&#xff0c;为进一步加强新时代教师队伍建设改革&#xff0c;促进人才培养能力和服务企业能力“双提升”&#xff0c;7月2日&#xff0c;“2024企业实践工业互联网职业教育师资培训班”在蓝卓顺利开班。 来自宁波城市职业技术学院、宁波职业技…

代理IP和VPN有什么区别?该怎么选择?

今天我们来聊聊很多人关心的一个问题——代理IP和VPN到底有什么区别&#xff1f;虽然它们听起来差不多&#xff0c;但其实有很大的不同。这篇文章&#xff0c;小编就带大家一起了解一下吧&#xff01; 什么是代理IP&#xff1f; 代理IP是一种通过代理服务器替换用户真实IP地址…

c进阶篇(四):内存函数

内存函数以字节为单位更改 1.memcpy memcpy 是 C/C 中的一个标准库函数&#xff0c;用于内存拷贝操作。它的原型通常定义在 <cstring> 头文件中&#xff0c;其作用是将一块内存中的数据复制到另一块内存中。 函数原型&#xff1a;void *memcpy(void *dest, const void…