Linux系统编程(信号处理 sigacation函数和sigqueue函数 )

news2024/11/24 20:07:13

文章目录

  • 前言
  • 一、sigaction
  • 二、sigqueue函数
  • 三、代码示例
  • 总结


前言

本篇文章我们来介绍一下sigacation函数和sigqueue函数。

一、sigaction

sigaction 是一个用于设置和检查信号处理程序的函数。它允许我们指定信号的处理方式,包括指定一个函数作为信号处理程序、设置标志位以及指定信号处理程序执行期间的信号屏蔽字等信息。

下面是 sigaction 函数的原型:

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

signum:要操作的信号的编号。可以是 POSIX 信号常量(如 SIGINT、SIGTERM 等)或自定义信号的编号。

act:一个指向 struct sigaction 结构的指针,包含了要设置的信号的处理方式和信号标志等信息。

oldact:一个可选的指向 struct sigaction 结构的指针。如果不为 NULL,将返回之前的信号处理程序的信息。

struct sigaction 结构体是用来描述信号的处理方式和信号标志等信息的,其定义如下:

struct sigaction {
    void (*sa_handler)(int);                  // 信号处理程序的函数指针
    sigset_t sa_mask;                          // 信号屏蔽字
    int sa_flags;                              // 信号标志
    void (*sa_sigaction)(int, siginfo_t *, void *);   // 使用 sa_sigaction 代替 sa_handler
};

sa_handler:一个函数指针,指向信号处理程序的函数。可以是一个用户定义的函数,也可以是特殊的值 SIG_DFL(默认处理程序)或 SIG_IGN(忽略处理程序)。

sa_mask:一个信号集,用来指定在信号处理程序执行期间要屏蔽的信号。它影响信号处理程序的上下文,可以通过 sigaddset、sigemptyset 等函数进行设置。

sa_flags:一组标志位,用于指定信号处理程序的行为。常见的标志位包括 SA_RESTART(在被信号中断的系统调用后自动重启)和 SA_NODEFER(在调用信号处理程序时不将本信号添加到进程的信号屏蔽字中)等。

sa_sigaction:一个函数指针,用于指定信号的扩展处理程序。它支持更多的参数,包括一个 siginfo_t 类型的结构体和一个 void * 类型的指针,用于传递关于信号的更多信息。

通过使用 sigaction 函数,我们可以设置信号处理程序的行为,包括调用用户定义的函数、忽略信号、重新启动系统调用等,并可以设置信号屏蔽字,以控制信号传递的方式。这使得我们可以对不同的信号进行个性化的处理。

siginfo_t 结构体是在信号处理程序中提供有关接收到信号的更详细信息的数据结构。它定义在 <signal.h> 头文件中,用于在处理程序中获取有关信号的附加信息。

下面是 siginfo_t 结构体的基本定义:

typedef struct siginfo {
    int si_signo;             // 信号编号
    int si_errno;             // 相关错误代码
    int si_code;              // 附加信号码
    pid_t si_pid;             // 发送信号的进程ID
    uid_t si_uid;             // 发送信号的用户ID
    void *si_addr;            // 引起信号的内存地址
    int si_status;            // 进程状态(仅在 SIGCHLD 信号中使用)
    long si_band;             // 事件发生的条件(仅在 SIGPOLL 信号中使用)
    struct sigval si_value;   // 附加的数据值
    union sigval si_utime;    // 用户CPU时间的计数值(仅在 SIGCHLD 信号中使用)
    union sigval si_stime;    // 系统CPU时间的计数值(仅在 SIGCHLD 信号中使用)
} siginfo_t;

二、sigqueue函数

sigqueue 函数用于向指定的进程发送特定的信号,并且可以传递一个额外的数据值。它提供了比 kill 函数更丰富的功能,可以用于进程间的高级通信。

以下是 sigqueue 函数的基本定义:

int sigqueue(pid_t pid, int sig, const union sigval value);

pid 是接收信号的进程的进程ID。
sig 是要发送的信号的编号,可以是标准信号(如 SIGTERM,SIGINT 等)或用户定义的信号。
value 是一个 union sigval 类型的结构体,用于传递附加的数据值。

使用 sigqueue 函数发送信号的步骤如下:

1.创建一个 union sigval 结构体并设置相应的值,以便将额外的数据传递给接收进程。

2.调用 sigqueue 函数,将目标进程的进程ID、信号编号和数据值作为参数传递给它。

3.如果成功发送信号,sigqueue 函数将返回0;如果出错,返回-1,并设置相应的错误码。

通过使用 sigqueue 函数发送带有附加数据的信号,接收进程可以从信号处理程序中获取这些附加数据,并根据需要采取相应的操作。这对于进程间的通信很有用,可以用于传递消息、触发特定的操作,或者向其他进程传递数据。

需要注意的是,接收进程必须正确设置信号处理程序来处理通过 sigqueue 函数发送的信号,并正确解析读取附加数据。

三、代码示例

接收信号处理函数:

#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>

void signal_Handle(int sig, siginfo_t* info, void* ucontext)
{
    printf("handler : sig = %d\n", sig);
    printf("handler : info->si_signo = %d\n", info->si_signo);
    printf("handler : info->si_code = %d\n", info->si_code);
    printf("handler : info->si_pid = %d\n", info->si_pid);
    printf("handler : info->si_value = %d\n", info->si_value.sival_int);
}

int main(int argc, char** argv)
{
    printf("pid :%d\n", getpid());

    struct sigaction act = {0};

    act.sa_sigaction = signal_Handle;
    act.sa_flags = SA_RESTART | SA_SIGINFO;

    /* 添加信号屏蔽字 */
    /* 下面信号在信号处理程序执行时会被暂时阻塞 */
    sigaddset(&act.sa_mask, 40);
    sigaddset(&act.sa_mask, SIGINT);

    /* 设置信号的处理行为,设置后40和SIGINT信号将由act里面的信号处理函数处理 */
    sigaction(40, &act, NULL);
    sigaction(SIGINT, &act, NULL);

    while(1)
    {
        sleep(1);
    }

    return 0;
}

发送信号处理函数:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>


int main(int argc, char** argv)
{
    pid_t pid = atoi(argv[1]);

    union sigval sv = {123456};
    
    sigqueue(pid, 40, sv);

    raise(SIGINT); 

    return 0;
}

运行结果:

从结果中我们可以看出接收到信号后打印出了对应的数据。
在这里插入图片描述

总结

本篇文章主要讲解了sigacation函数和sigqueue函数,相比于signal和kill函数,使用这两个函数来发送信号是比较灵活的。

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

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

相关文章

AsyncImage, BackgroundMaterials, TextSelection, ButtonStyles 的使用

1. AsyncImage 异步加载图片 1.1 实现 /*case empty -> No image is loaded.case success(Image) -> An image succesfully loaded.case failure(Error) -> An image failed to load with an error.*/ /// iOS 15 开始的 API 新特性示例 /// 异步加载图片 struct As…

Ae 效果:CC Plastic

风格化/CC Plastic Stylize/CC Plastic CC Plastic&#xff08;CC 塑料&#xff09;效果用于创建具有塑料质感的图像或视频效果&#xff0c;它模拟了塑料材质的外观特性&#xff0c;包括光照反射、表面凹凸以及光泽效果等。 ◆ ◆ ◆ 效果属性说明 Surface Bump 表面凹凸 通过…

IoT 场景下 TDengine 与老牌时序数据库怎么选?看看这份TSBS报告

上周一&#xff0c;TDengine 正式发布了 IoT 场景下基于 TSBS 的时序数据库&#xff08;Time Series Database&#xff0c;TSDB&#xff09;性能基准测试报告。该报告模拟虚拟货运公司车队中一组卡车的时序数据&#xff0c;预设了五种卡车规模场景&#xff0c;在相同的 AWS 云环…

[Lesson 01] TiDB数据库架构概述

目录 一 章节目标 二 TiDB 体系结构 1 TiDB Server 2.1 TiKV 2.2 TiFlash 3 PD 参考 一 章节目标 理解TiDB数据库整体架构了解TiDB Server TiKV tiFlash 和 PD的主要功能 二 TiDB 体系结构 了解这些体系结构是如何实现TiDB的核心功能的 1 TiDB Server TiDB Serve…

记录--你知道Vue中的Scoped css原理么?

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 追忆Scoped 偶然想起了一次面试&#xff0c;二面整体都聊完了&#xff0c;该做的算法题都做出来了&#xff0c;该背的八股文也背的差不多了&#xff0c;面试官频频点头&#xff0c;似乎对我的基础和项…

云计算的学习(四)

四、云计算中的存储基础知识 1.云计算虚拟化中的存储架构 ①虚拟化存储 在虚拟化存储架构中&#xff0c;最底层为物理磁盘。 底层的硬件组成存储池&#xff0c;存储池分为NAS存储和SAN存储&#xff1b;NAS存储需要文件系统&#xff1b;SAN存储需要对存储池进行逻辑划分产生逻…

【VSCode | 使用技巧集锦】中文插件突然失效、配置单个工程(工作区)编码

目录 ✨技巧一&#xff1a;中文插件失效的解决办法✨技巧二&#xff1a;配置单个工程(工作区)编码 ✨技巧一&#xff1a;中文插件失效的解决办法 问题描述&#xff1a;VSCode之前安装了中文插件&#xff0c;可以正常汉化&#xff0c;用了一段时间都没问题&#xff0c;今天打开v…

springboot+webscoket通信功能

1. 背景 项目上需要对某个页面的设计功能&#xff08;低代码&#xff09;进行最简单的多人协同&#xff0c;有以下需求点&#xff1a; &#xff08;1&#xff09;第一个进入该设计页面的人给编辑权限&#xff0c;后进入的所有人给在线&#xff08;可申请编辑&#xff09;权限 …

使用MQTTX和前端vue进行通讯

需求&#xff1a;根据后端给的接口&#xff0c;前端实现消息订阅和消息加密连接操作&#xff0c;不走后端直接和硬件设备进行操作 1.下载mqttx 官网链接&#xff1a;MQTTX: Your All-in-one MQTT Client Toolbox 根据自己电脑选择不同的操作系统&#xff0c;默认下载后是英文…

金鸣表格识别中何时应勾选“手写”选项?

在金鸣表格文字识别系统的表格识别模块中&#xff0c;有个“手写”的复选框可供用户选择性使用。这里的“手写”是手写识别的简称&#xff0c;设置此项的目的是为了让用户更准确地识别手写的表格图片中的文字。为何要单独设置这个选项而不是由程序全自动地进行处理呢&#xff1…

【GitOps系列】K8s极简实战

文章目录 示例应用介绍部署应用到k8s 如何使用命名空间隔离团队及应用环境&#xff1f;如何为业务选择最适合的工作负载类型&#xff1f;如何解决服务发现问题&#xff1f;如何迁移应用配置&#xff1f;如何将集群的业务服务暴露外网访问&#xff1f;如何保障业务资源需求和自动…

JavaWeb(3)——HTML、CSS、JS 快速入门

一、JavaScript 运算符 • 赋值运算符&#xff08; &#xff09; 赋值运算符执行过程&#xff1f; 将等号右边的值赋予给左边, 要求左边必须是一个容器 出现是为了简化代码, 比如让 let age 18 &#xff0c;age 加 2 怎么写呢 let age 18age 2console.log(age)age * 2con…

html+JavaScript实现一个好看的颜色码查询器,支持查询、转换、颜色选择器和颜色码对照表

前言 相信大家平时工作的时候应该会经常用到颜色码吧&#xff0c;比如说想找个好看的颜色&#xff0c;或者有个颜色码但是不知道这个码是什么颜色的&#xff0c;这个时候我们就可以用颜色码对照表或者颜色码查询来查看了。 当然也可以用截图软件或者取色器或者PS来查看&#…

如何有效检测、识别和管理 Terraform 配置漂移?

作者&#xff5c;Krishnadutt Panchagnula 翻译&#xff5c;Seal软件 链接&#xff5c;https://betterprogramming.pub/detecting-identifying-and-managing-terraform-state-drift-997366a74537 在理想的 IaC 世界中&#xff0c;我们所有的基础设施实现和更新都是通过将更新的…

【高并发】高并发架构实战:从需求分析到系统设计

Yan-英杰的主页 悟已往之不谏 知来者之可追 C程序员&#xff0c;2024届电子信息研究生 很多软件工程师的职业规划是成为架构师&#xff0c;但是要成为架构师很多时候要求先有架构设计经验&#xff0c;而不做架构师又怎么会有架构设计经验呢&#xff1f;那么要如何获得架构设…

Cesium 测距、测面功能实现

参考博主 功能代码参考 新需求&#xff1a;点击测距&#xff0c;此时画线逻辑已生成到运行缓存中&#xff0c;如果 用户误触测距&#xff0c;想撤销&#xff0c;如何操作&#xff1f; 代码&#xff1a; // 重置画图resetDraw(){// 清除可能会用到的监听事件if (this.handle…

操作系统17:外存组织方式和文件存储管理

目录 1、外存的组织方式 &#xff08;1&#xff09;连续组织方式 &#xff08;2&#xff09;链接组织方式 2.1 - 隐式链接 2.2 - 显式链接 &#xff08;3&#xff09;索引组织方式 3.1 - 单级索引组织方式 3.2 - 多级索引组织方式 3.3 - 增量式索引组织方式 2、文件存…

【操作系统】几种基本页面置换算法的基本思想和流程图

目录 一、概述二、最佳置换算法&#xff08;OPT&#xff09;三、先进先出置换算法&#xff08;FIFO&#xff09;四、最近最久未使用置换算法&#xff08;LRU&#xff09;五、三种页面置换算法优缺点对比六、运行结果七、总结 一、概述 在地址映射过程中&#xff0c;若在页面中发…

Linux 发行版 Gentoo 存在重大漏洞

导读网络安全公司 SonarSource 在日前研究中发现&#xff0c;Gentoo Linux 发行版中存在漏洞 CVE-2023-28424&#xff0c;黑客可以利用该漏洞进行 SQL 注入攻击。 研究人员从 GentooLinux 的 Soko 搜索组件中找到了这个漏洞。该漏洞的 CVSS 风险评分为 9.1&#xff0c;属于特别…

6款开源中文OCR使用介绍(亲测效果)

文章目录 前言开源ocr项目1. Paddle OCR&#xff08;推荐指数&#xff1a;★★★★★&#xff09;1.1 简介1.2 使用1.3 优缺点 2. CnOCR&#xff08;推荐指数&#xff1a;★★★★★&#xff09;2.1 简介2.2 使用2.3 优缺点 3. chinese_lite OCR&#xff08;推荐指数&#xff1…