嵌入式Linux系统编程 — 6.7 实时信号

目录

1 什么是实时信号

2 sigqueue函数

3 sigpending()函数


1 什么是实时信号

等待信号集只是一个掩码,它并不追踪信号的发生次数。这意味着,如果相同的信号在被阻塞的状态下多次产生,它只会在信号集中被记录一次,并且在信号集被检查时仅被视为一个事件。这是标准信号的缺点之一。

与标准信号不同,实时信号可以排队,如果同一个实时信号多次发送给同一个进程,它们将被排队处理,而不是像标准信号那样只能触发一次。实时信号较之于标准信号,其优势如下:

  • 可排队: 实时信号可以排队等待处理,如果一个信号多次到达,它只会被处理一次,除非它被显式地从队列中移除并重新发送。
  • 优先级队列: 实时信号具有与信号相关联的默认实时优先级。如果一个实时信号被发送,它将按照其优先级顺序处理,这有助于确保高优先级的信号能够及时被处理。

  • 应用定义的处理: 实时信号可以有应用程序定义的处理函数,类似于传统信号,但是它们可以安全地使用在多线程环境中。

  • 不干扰传统信号: 实时信号与标准信号(如 SIGKILLSIGSTOP)分开处理,因此不会受到这些信号的影响。

Linux 内核定义了 31 个不同的实时信号,信号编号范围为 34~64,使用 SIGRTMIN 表示编号最小的实时信号,使用 SIGRTMAX 表示编号最大的实时信号,其它信号编号可使用这两个宏加上一个整数或减去一个整数。

应用程序当中使用实时信号,需要有以下的两点要求:

  • 发送进程使用 sigqueue()系统调用向另一个进程发送实时信号以及伴随数据。

  • 接收实时信号的进程要为该信号建立一个信号处理函数,使用sigaction函数为信号建立处理函数,并加入 SA_SIGINFO,这样信号处理函数才能够接收到实时信号以及伴随数据,也就是要使用sa_sigaction 指针指向的处理函数,而不是 sa_handler,当然允许应用程序使用 sa_handler,但这样就不能获取到实时信号的伴随数据了。

2 sigqueue函数

sigqueue() 函数是用于发送实时信号给指定进程的 POSIX 函数。实时信号是 POSIX 1003.1b 标准的一部分,它们允许发送者指定信号的属性,如信号值和与之关联的数据。函数原型如下:

#include <signal.h>int sigqueue(pid_t pid, int sig, const union sigval value);
  • pid:接收信号的进程的进程 ID。如果 pid 为负值,信号将发送给指定会话中的所有进程。
  • signum:要发送的信号的编号。它应该是 SIGRTMIN 到 SIGRTMAX 之间的值,表示一个实时信号。
  • value:参数 value 指定了信号的伴随数据, union sigval 数据类型。
  • 返回值:成功时返回 0,失败时返回 -1,并设置 errno 以指示错误。

union sigval 数据类型(共用体) 如下所示:

typedef union sigval
{int sival_int;void *sival_ptr;
} sigval_t;

下面的示例代码是一个基本的父子进程通信程序,其中父进程使用 sigqueue 函数向子进程发送一个信号和附加数据。

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>int main() 
{pid_t pid = fork(); // 创建子进程if (pid == -1) {perror("fork failed");exit(EXIT_FAILURE);}if (pid == 0) {// 子进程printf("Child process is waiting for signal...\n");pause(); // 子进程挂起,等待信号exit(EXIT_FAILURE); // 确保子进程在接收信号前不会退出} else {// 父进程printf("Parent process is sending signal to child...\n");sleep(2); // 让子进程先打印等待信息// 声明sigval变量并初始化union sigval value;value.sival_ptr = "Hello from parent!"; // 设置信号值if (sigqueue(pid, SIGUSR1, value) == -1) {perror("sigqueue failed");exit(EXIT_FAILURE);}printf("Signal sent successfully.\n");int status;waitpid(pid, &status, 0); // 等待子进程结束if (WIFEXITED(status)) {printf("Child exited with status %d\n", WEXITSTATUS(status));}}return 0;
}

在这段代码中,父进程首先创建了一个子进程,然后子进程调用 pause 进入等待状态,直到接收到信号。父进程在稍作延时后使用 sigqueue 发送 SIGUSR1 信号给子进程,并附带一个 sigval 类型的联合体,其中 sival_ptr 成员指向一个字符串 "Hello from parent!"。如果 sigqueue 调用成功,父进程将打印一条成功消息,并等待子进程结束。父进程随后检查子进程的退出状态,并打印出来。

3 sigpending()函数

sigpending 函数用于查询系统中挂起(pending)的信号集,挂起的信号是指那些已经发送给进程,但尚未被进程处理的信号。函数原型如下:

#include <signal.h> int sigpending(set_t *set);
  • set_t:处于等待状态的信号会存放在参数 set 所指向的信号集中。

下面是一个简单的使用 sigpending 函数的示例:

#include <stdio.h>
#include <signal.h>
#include <errno.h>int main() 
{sigset_t pending_set;// 检查错误if (sigpending(&pending_set) == -1) {perror("sigpending failed");return 1;}// 检查特定信号是否挂起if (sigismember(&pending_set, SIGINT)) {printf("SIGINT is pending.\n");} else {printf("SIGINT is not pending.\n");}return 0;
}

在这个示例中,程序首先调用 sigpending 来获取当前挂起的信号集,然后使用 sigismember 函数检查 SIGINT是否在挂起信号集中。如果 SIGINT 信号挂起,程序将打印相应的消息。如果 sigpending 调用失败,程序将打印错误信息并返回。

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

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

相关文章

SLAM 精度评估

SLAM 精度的评估有两个最重要的指标&#xff0c;即绝对轨迹误差&#xff08;ATE&#xff09;和相对位姿误差&#xff08;RPE&#xff09;的 均方根误差&#xff08;RMSE&#xff09;: 绝对轨迹误差:直接计算相机位姿的真实值与 SLAM 系统的估计值之间的差值&#xff0c;首先将…

kubernetes service 服务

1 service作用 使用kubernetes集群运行工作负载时&#xff0c;由于Pod经常处于用后即焚状态&#xff0c;Pod经常被重新生成&#xff0c;因此Pod对应的IP地址也会经常变化&#xff0c;导致无法直接访问Pod提供的服务&#xff0c;Kubernetes中使用了Service来解决这一问题&#…

【Linux】多线程(互斥 同步)

我们在上一节多线程提到没有任何保护措施的抢票是会造成数据不一致的问题的。 那我们怎么办&#xff1f; 答案就是进行加锁。 目录 加锁&#xff1a;认识锁和接口&#xff1a;初始化&#xff1a;加锁 && 解锁&#xff1a;全局的方式&#xff1a;局部的方式&#xff1a…

【SkiaSharp绘图15】SKPath属性详解:边界、填充、凹凸、类型判断、坐标、路径类型

文章目录 SKPath 构造函数SKPath 属性Bounds 边界(宽边界)TightBounds紧边界FillType填充方式IsConcave 是否凹/ IsConvex 是否凸IsEmpty是否为空IsLine是否为线段IsRect是否为矩形IsOval是否为椭圆或圆IsRoundRect是否为圆角矩形Item[] 获取路径的坐标LastPoint最后点的坐标Po…

2024最全软件测试面试八股文(答案+文档+视频讲解)

Part1 1、你的测试职业发展是什么&#xff1f; 测试经验越多&#xff0c;测试能力越高。所以我的职业发展是需要时间积累的&#xff0c;一步步向着高级测试工程师奔去。而且我也有初步的职业规划&#xff0c;前3年积累测试经验&#xff0c;按如何做好测试工程师的要点去要求自…

OrangePi AIpro开发板测评 —— 相机图像获取

&#x1f482; 个人主页: 同学来啦&#x1f91f; 版权: 本文由【同学来啦】原创、在CSDN首发、需要转载请联系博主 &#x1f4ac; 如果文章对你有帮助&#xff0c;欢迎关注、点赞、收藏和订阅专栏哦 文章目录 &#x1f31f; 一、引言&#x1f31f; 二、OrangePi AIpro 简要介绍…

力扣206

题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&#xff1a;[2,1]示例 3&#xff1a; 输…

基于Transformer的端到端的目标检测 | 读论文

本文正在参加 人工智能创作者扶持计划 提及到计算机视觉的目标检测&#xff0c;我们一般会最先想到卷积神经网络&#xff08;CNN&#xff09;&#xff0c;因为这算是目标检测领域的开山之作了&#xff0c;在很长的一段时间里人们都折服于卷积神经网络在图像处理领域的优势&…

【数据库】E-R图、E-R模型到关系模式的转换、关系代数表达式、范式

一、E-R图 1、基本概念 2、实体集之间的联系 3、E-R图要点 &#xff08;1&#xff09;实体&#xff08;型&#xff09;的表示 &#xff08;2&#xff09;E-R图属性的表示 &#xff08;3&#xff09;联系的表示 4、E-R模型的例题 二、E-R模型到关系模式的转换 1、实体型的转换…

使用getline()从文件中读取一行字符串

我们知道&#xff0c;getline() 方法定义在 istream 类中&#xff0c;而 fstream 和 ifstream 类继承自 istream 类&#xff0c;因此 fstream 和 ifstream 的类对象可以调用 getline() 成员方法。 当文件流对象调用 getline() 方法时&#xff0c;该方法的功能就变成了从指定文件…

基于STM32F103C8T6的同步电机驱动-CubeMX配置与IQmath调用

基于STM32F103C8T6的同步电机驱动-CubeMX配置与IQmath调用 一、功能描述: 上位机通过CAN总线实现对电机的运动控制,主要包含三种模式:位置模式、速度模式以及力矩模式。驱动器硬件核心为STM32F103C8T6,带相电压采集电路以及母线电压采集电路。其中供电电压12V。 PWM中心对…

【单片机毕业设计选题24047】-基于阿里云的工地环境监测系统

系统功能: 基于STM32完成 主机&#xff08;阿里云以及oled屏显示位置一&#xff09;&#xff1a;烟雾检测&#xff0c;温湿度检测&#xff0c;噪声检测&#xff0c;且用OLED屏显示&#xff0c;设置阈值&#xff0c;超过报警&#xff08;蜂鸣器&#xff09;。 从机&#xff0…

LeetCode题练习与总结:对链表进行插入排序--147

一、题目描述 给定单个链表的头 head &#xff0c;使用 插入排序 对链表进行排序&#xff0c;并返回 排序后链表的头 。 插入排序 算法的步骤: 插入排序是迭代的&#xff0c;每次只移动一个元素&#xff0c;直到所有元素可以形成一个有序的输出列表。每次迭代中&#xff0c;…

Element中的日期时间选择器DateTimePicker和级联选择器Cascader

简述&#xff1a;在Element UI框架中&#xff0c;Cascader&#xff08;级联选择器&#xff09;和DateTimePicker&#xff08;日期时间选择器&#xff09;是两个非常实用且常用的组件&#xff0c;它们分别用于日期选择和多层级选择&#xff0c;提供了丰富的交互体验和便捷的数据…

【server】nacos 安装

1、本地安装 1.1 nacos官网 Nacos官网| Nacos 配置中心 | Nacos 下载| Nacos 官方社区 | Nacos 官网 git 下载地址&#xff1a;https://github.com/alibaba/nacos/releases 1.2 解压并修改配置 1.2.1 通过properties 修改配置&#xff0c;添加数据库配置 1.2.2 创建数据库&…

字节码编程ASM之生成变量并sout

写在前面 本文看下如何通过asm生成变量并sout。 1&#xff1a;代码 直接看代码吧&#xff0c;注释很详细&#xff0c;有不懂的&#xff0c;留言告诉我&#xff1a; package com.dahuyuo.asmtest;import org.objectweb.asm.*; import org.objectweb.asm.commons.AdviceAdapt…

VCS+Vivado联合仿真BUG

场景&#xff1a; 在vcsvivado联合仿真过程中&#xff0c;对vivado导出的shell脚本修改&#xff0c;修改某些source文件路径&#xff0c;vcs编译时会报Permission Denied。 问题描述 对shell脚本修改如下&#xff1a; 修改仅为注释掉某一行&#xff0c;下面变为source文件新…

Linux shell编程学习笔记62: top命令 linux下的任务管理器

0 前言 top命令是Unix 和 Linux下常用的性能分析工具&#xff0c;提供了一个动态的、交互式的实时视图&#xff0c;显示系统的整体性能信息&#xff0c;以及正在运行的进程的相关信息&#xff0c;包括各个进程的资源占用状况&#xff0c;类似于Windows的任务管理器。 1 top命令…

数据特征采样在 MySQL 同步一致性校验中的实践

作者&#xff1a;vivo 互联网存储研发团队 - Shang Yongxing 本文介绍了当前DTS应用中&#xff0c;MySQL数据同步使用到的数据一致性校验工具&#xff0c;并对它的实现思路进行分享。 一、背景 在 MySQL 的使用过程中&#xff0c;经常会因为如集群拆分、数据传输、数据聚合等…

【堆 优先队列】23. 合并 K 个升序链表

本文涉及知识点 堆 优先队列 LeetCode23. 合并 K 个升序链表 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中&#xff0c;返回合并后的链表。 示例 1&#xff1a; 输入&#xff1a;lists [[1,4,5],[1,3,4],[2,6]] 输出&#…