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

Linux系统编程---Signal信号集

0、前言

        在上一篇博客笔记文章中,对Linux进程间通信的信号进行了讲解,本章将接着上一篇文章的内容,继续对Linux进程间通信中信号部分的信号集这个小知识点进行梳理。

        如果有对Linux系统编程有不了解的地方,欢迎查阅博主的Linux系统编程专栏进行参考学习交流。

系统编程_奔跑的蜗牛!的博客-CSDN博客https://blog.csdn.net/weixin_49337111/category_12952742.html?spm=1001.2014.3001.5482

1、Linux信号集

(1)、什么是信号集?

        在 Linux 中,信号集(Signal Set)是一种用于管理和操作信号的数据结构。

        信号集是一个包含多个信号的集合,它可以用来表示一组需要被处理、阻塞或忽略的信号。每个信号在信号集中都有对应的标志位,通过对这些标志位的操作,可以方便地对一组信号进行统一的管理。

(2)、信号阻塞与信号忽略有什么区别?

        信号响应:收到信号之后,会响应信号的动作。

        信号忽略:收到信号之后,直接丢弃这个信号。

        信号阻塞:进程在阻塞某一个信号前提下,收到了这个信号,不会马上响应,而是要等到解除阻塞之后,才会响应这个信号。(这个信号没有被响应时,不会丢弃,而是放在一个挂起队列中)

2、信号集处理函数

(1)、 信号集如何定义?

        信号集其实就是一个变量,数据类型是: sigset_t。

        定义信号集: sigset_t set;

(2)、sigemptyset

//函数功能
用于初始化一个信号集,将信号集中的所有信号都清空,即设置为不包含任何信号。//函数原型
#include <signal.h>int sigemptyset(sigset_t *set);
//函数参数
set:指向要初始化的信号集的指针//函数返回值
成功时返回 0,出错时返回 - 1

(3)、sigfillset

//函数功能
用于将信号集中的所有信号位都设置为 1,即包含所有的信号//函数原型
#include <signal.h>int sigfillset(sigset_t *set);
//函数参数
set:指向要初始化的信号集的指针//函数返回值
成功时返回 0,出错时返回 - 1

(4)、sigaddset

//函数功能
用于将指定的信号添加到信号集中。//函数原型
#include <signal.h>int sigaddset(sigset_t *set, int signum);
//函数参数
set:指向要初始化的信号集的指针
signum:是要添加的信号编号//函数返回值
成功时返回 0,出错时返回 - 1

(5)、sigdelset

//函数功能
用于从信号集中删除指定的信号。//函数原型
#include <signal.h>int sigdelset(sigset_t *set, int signum);
//函数参数
set:指向要初始化的信号集的指针
signum:是要添加的信号编号//函数返回值
成功时返回 0,出错时返回 - 1

(6)、sigismember

//函数功能
用于检查指定的信号是否在信号集中。//函数原型
#include <signal.h>int sigismember(const sigset_t *set, int signum);
//函数参数
set:指向要初始化的信号集的指针
signum:是要添加的信号编号//函数返回值
成功时返回 0,出错时返回 - 1

(7)、信号集程序示例

        先清空信号集,再把SIGUSR1、SIGUSR2加入到集合中,判断信号是不是在集合中。

#include <stdio.h>
#include <signal.h>int main(int argc, char*argv[])
{//1)先定义一个信号集变量 sigset_t  set;//2) 初始化(清空)sigemptyset(&set); //清空信号集//3)将信号 添加到集合中 SIGUSR1  SIGUSR2sigaddset(&set, SIGUSR1); //在指定的信号集set中,添加一个指定的信号signum到集合中sigaddset(&set, SIGUSR2);//4) 判断 SIGUSR2信号是否在集合中,如果在打印Yes, 否则 打印No// sigismember 信号在集合中 返回1  否则 返回 0if(sigismember(&set, SIGUSR2)){printf("Yes\n");   } else {printf("No\n"); }return 0;
}

3、信号集状态设置

(1)、API接口

//函数功能
用于检查指定的信号是否在信号集中。//函数原型
#include <signal.h>int sigprocmask(int how, const sigset_t *restrict set,sigset_t *restrict oset);//函数参数
how:决定了信号掩码的修改方式SIG_BLOCK:把set信号集中包含的信号添加到当前信号掩码里,简单来说就是添加阻塞信号。SIG_UNBLOCK:从当前信号掩码中移除set信号集中包含的信号,也就是解除对这些信号的阻塞。SIG_SETMASK:直接用set信号集来替换当前的信号掩码。
set:它指向一个信号集如果how是SIG_BLOCK,则会阻塞这个信号集中的信号;如果how是SIG_UNBLOCK,则会解除对这些信号的阻塞;如果how为SIG_SETMASK,当前信号掩码就会被设置成这个信号集的内容。
oset:它指向一个信号集,用于保存调用该函数之前的信号掩码。如果不需要这个功能,可以把它设置为NULL。//函数返回值
成功时返回 0;出错时返回 - 1,并设置errno来指示具体的错误原因。

sigset set;

信号 -> set

sigprocmask(SIG_BLOCK,&set,NULL); -> 设置为阻塞

...

sigprocmask(SIG_UNBLOCK,&set,NULL); -> 解除阻塞

(2)、程序示例

#include<stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>#include <string.h>
#include <sys/wait.h>
#include <signal.h>void signalHandle(int signum)
{printf("捕捉到%d信号,去执行别的事情.....\n",signum);int cnt = 5;while(cnt--){sleep(1);printf("我正在清理 垃圾...%d\n",cnt);}
}//SIGINT
int main(int argc,char**argv)  // ./a.out  46725
{//将SIGUSR2 信号 设置 一个信号响应函数signal(SIGUSR2,signalHandle);signal(60,signalHandle);//1、先定义一个信号集合变量  ---数组 sigset_t set;//2、清空 信号集合变量   -----数组清空sigemptyset(&set);//3、将你想要设置的信号  一个个 地加入 到 集合变量中   --数组中每个元素 挨个进行赋值 sigaddset(&set,SIGUSR1);    sigaddset(&set,SIGUSR2);sigaddset(&set,60);//将上面的信号集合set中的所有信号  设置 为  阻塞状态sigprocmask(SIG_BLOCK, &set,NULL);int cnt = 30;while(cnt--){sleep(1);printf("[%d]主进程正在执行很重要任务%d.....\n",getpid(),cnt);}//等上面很重要的事情 完成了,再解除阻塞 ,响应信号sigprocmask(SIG_UNBLOCK, &set,NULL);return 0;
}

        在上述程序运行中,使用kill命令,对该进程发送信号,在信号集解除阻塞状态后,开始响应。

        kill -60 6374

        kill -SIGUSR2 6374

http://www.xdnf.cn/news/5932.html

相关文章:

  • Profibus DP主站转Modbus RTU/TCP如何把E+H流量计接入到modbus
  • 基于单片机的视力保护仪设计与实现
  • 硬密封保温 V 型球阀:恒温工况下复杂介质控制的性价比之选-耀圣
  • RabbitMQ 核心概念与消息模型深度解析(一)
  • Linux 系统如何挂载U盘
  • 火语言RPA--EcshopV4发布商品
  • 【datawhale组队学习】coze-ai-assistant TASK01
  • 【ROS2实战】在中国地区 Ubuntu 22.04 上安装 ROS 2 Humble 教程
  • 黑白浮生项目测试报告
  • k8s初始化时候,报错无法通过 CRI(容器运行时接口)与 containerd 通信
  • 5.13 note
  • Java反射详细介绍
  • AI 检测原创论文:技术迷思与教育本质的悖论思考
  • 组策略+注册表解决 系统还原 被禁问题
  • 推荐系统-基于特征掩码的自适应特征建模: AdaF^2M^2(DASFAA‘2025)
  • 【GNSS硬件接收机】【非公开文章】GNSS硬件接收机设计目录
  • JavaScript 模块封装函数
  • 函数加密(Functional Encryption)简介
  • 信奥赛-刷题笔记-队列篇-T2-P1540机器翻译和P2952Cow Line S
  • 抗菌肽Tet-213,1260528-09-3
  • Java并发编程-线程池(二)
  • 今日行情明日机会——20250513
  • 期货反向跟单软件—持仓上限控制功能
  • gcc和g++
  • 闭包原理与常见陷阱
  • 装饰器在Python中的作用及在PyTorchMMDetection中的实战应用
  • Python -将MP4文件转为GIF图片
  • MyBatis 批量新增与删除功能完整教程
  • SpringBoot的外部化配置
  • 软件测试(1) 软件测试概述