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

lv5 嵌入式开发-10 信号机制(下)

目录

1 信号集、信号的阻塞

2 信号集操作函数

2.1 自定义信号集

2.2 清空信号集

2.3 全部置1

2.4 将一个信号添加到集合中

2.5 将一个信号从集合中移除

2.6 判断一个信号是否在集合中

2.7 设定对信号集内的信号的处理方式(阻塞或不阻塞)

2.8  使进程挂起(暂停执行)直到收到一个信号

2.9 更改进程的信号屏蔽字,并等待一个特定的信号到来


掌握:信号集和信号屏蔽

1 信号集、信号的阻塞

应用:

有时候不希望在接到信号时就立即停止当前执行,去处理信号,同时也不希望忽略该信号,而是延

时一段时间去调用信号处理函数。这种情况可以通过阻塞信号实现。

信号的阻塞概念

信号的”阻塞“是一个开关动作,指的是阻止信号被处理,但不是阻止信号产生。

信号的状态:

信号递达(Delivery ):实际信号执行的处理过程(3种状态:忽略,执行默认动作,捕获)

信号未决(Pending):从产生到递达之间的状态(挂起)

下图表示了,每一个任务控制块都有一个挂起信号集(可读)和信号屏蔽字(可写可读)。信号屏蔽置1,代表忽略该信号的到来

2 信号集操作函数

2.1 自定义信号集

sigset_t set; 

自定义信号集。  是一个  64bit  128bit的数组。

2.2 清空信号集

sigemptyset(sigset_t *set);	

代表接收所有信号

2.3 全部置1

sigfillset(sigset_t *set);	

接收全部信号

2.4 将一个信号添加到集合中

sigaddset(sigset_t *set, int signum);	

接收某一个位的信号

2.5 将一个信号从集合中移除

sigdelset(sigset_t *set, int signum);	

屏蔽某一个位的信号

2.6 判断一个信号是否在集合中

sigismember(const sigset_t *set,int signum); 

2.7 设定对信号集内的信号的处理方式(阻塞或不阻塞)

#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:指向要修改的新的信号屏蔽字的指针。如果为NULL,则不会修改信号屏蔽字。
  • oset:用于保存旧的信号屏蔽字的指针。如果为NULL,则不会保存旧的信号屏蔽字。

函数返回值:

  • 成功:返回0,并将旧的信号屏蔽字保存到oset中(如果oset不为NULL)。
  • 失败:返回-1,并设置errno来指示错误的原因。

该函数用于在多线程编程、信号处理等场景中控制信号的屏蔽,以保证信号处理的正确性和可靠性。

示例:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>void handle(int sig){printf("I get sig=%d\n",sig);}int main(){struct sigaction act;act.sa_handler = handle;   //注册回调函数sigemptyset(&act.sa_mask); //清空信号集,代表接收所有信号act.sa_flags = 0;          //通过将其设置为0,表示不使用任何额外的标志位,即默认行为。sigaction(SIGINT,&act,NULL); //信号捕获sigset_t set;               //定义信号集sigemptyset(&set);          //清空信号集sigaddset(&set,SIGINT);     //SIGINT,屏蔽SIGINT信号sigprocmask(SIG_BLOCK,&set,NULL);  //ctrl+c的信号阻塞,接收不到sleep(5);sigprocmask(SIG_UNBLOCK,&set,NULL); //取消信号阻塞while(1){sleep(1);}}

执行效果 :

2.8  使进程挂起(暂停执行)直到收到一个信号

int pause(void);

进程一直阻塞,直到被信号中断,返回值:-1 并设置errno为EINTR

函数行为:

-1 如果信号的默认处理动作是终止进程,则进程终止,pause函数没有机会返回。

-2 如果信号的默认处理动作是忽略,进程继续处于挂起状态,pause函数不返回

-3 如果信号的处理动作是捕捉,则调用完信号处理函数之后,pause返回-1。

-4 pause收到的信号如果被屏蔽,那么pause就不能被唤醒 

示例:pause阻塞效果

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main(int argc, char * argv[])
{pause();printf("after pause\n");
}//运行后结果程序阻塞中,未打印after pause,按ctrl+c或ctrl+\结束
linux@linux:~/Desktop$ ./pause 

 示例:pause阻塞效果2

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>void handle(int sig)
{printf("Handle:I get sig=%d\n",sig);
}int main(int argc, char * argv[])
{struct sigaction act;act.sa_handler = handle;act.sa_flags = 0;sigemptyset(&act.sa_mask);sigaction(SIGINT,&act,NULL);pause();printf("after pause\n");
}//运行结果,未恢复至原处理函数的执行效果
linux@linux:~/Desktop$ ./pause 
^CHandle:I get sig=2
after pause
linux@linux:~/Desktop$

 示例:pause阻塞效果3 ,实现一个等待信号的任务

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>void handle(int sig)
{printf("Handle:I get sig=%d\n",sig);
}void mytask()
{printf("mytask:start\n");sleep(3);printf("mytask:end\n");
}int main(int argc, char * argv[])
{struct sigaction act;act.sa_handler = handle;act.sa_flags = 0;sigemptyset(&act.sa_mask);sigaction(SIGINT,&act,NULL);pause();while(1){mytask();   pause();   //每次等待信号到来再执行mytask}printf("After pause\n");
}  //运行结果
linux@linux:~/Desktop$ ./pause 
^CHandle:I get sig=2
mytask:start
mytask:end
^CHandle:I get sig=2
mytask:start
mytask:end
^CHandle:I get sig=2
mytask:start
mytask:end

使用kill 发送SIGHUP信号关闭 

  示例:pause阻塞效果4 ,实现一个等待多个信号的任务(SIGINT,SIGHUP)

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>void handle(int sig)
{printf("Handle:I get sig=%d\n",sig);
}void mytask()
{printf("mytask:start\n");sleep(3);printf("mytask:end\n");
}int main(int argc, char * argv[])
{struct sigaction act;act.sa_handler = handle;act.sa_flags = 0;sigemptyset(&act.sa_mask);sigaction(SIGINT,&act,NULL);sigaction(SIGHUP,&act,NULL);	pause();while(1){mytask();pause();}printf("After pause\n");
}

按ctrl+c,或者使用kill -1发送关闭信号都可以捕获信号处理任务。

 示例:使用 sigaddset,屏蔽多个信号

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>void handle(int sig)
{printf("Handle:I get sig=%d\n",sig);
}void mytask()
{printf("mytask:start\n");sleep(3);printf("mytask:end\n");
}int main(int argc, char * argv[])
{struct sigaction act;act.sa_handler = handle;act.sa_flags = 0;sigemptyset(&act.sa_mask);sigaction(SIGINT,&act,NULL);sigaction(SIGHUP,&act,NULL);sigset_t set;sigaddset(&set,SIGHUP);sigaddset(&set,SIGINT);	pause();while(1){sigprocmask(SIG_BLOCK,&set,NULL);mytask();sigprocmask(SIG_UNBLOCK,&set,NULL);pause();}printf("After pause\n");
}

执行效果,在任务过程中设置了信号屏蔽,此时按ctrl+c或者kill -1去发送信号,不会执行handle打印,直到任务结束后再开启接收信号,防止任务被打断

2.9 更改进程的信号屏蔽字,并等待一个特定的信号到来

设定对信号集内的信号屏蔽并恢复。

int sigsuspend(const sigset_t *sigmask);

功能:函数用于临时更改进程的信号屏蔽字,并等待一个特定的信号到来,然后恢复原有的信号屏蔽字。和 pause 函数不同的是,它可以临时更改进程的信号屏蔽字,以便等待某个特定信号。

参数:

sigmask:希望屏蔽的信号

示例:解决任务中的信号丢失问题,sigsuspend相当于sigprocmask+pause

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>void handle(int sig)
{printf("Handle:I get sig=%d\n",sig);
}void mytask()
{printf("mytask:start\n");sleep(3);printf("mytask:end\n");
}int main(int argc, char * argv[])
{struct sigaction act;act.sa_handler = handle;act.sa_flags = 0;sigemptyset(&act.sa_mask);sigaction(SIGINT,&act,NULL);sigaction(SIGHUP,&act,NULL);sigset_t set;sigaddset(&set,SIGHUP);sigaddset(&set,SIGINT);	sigset_t set2;                sigemptyset(&set2);         //接收所有信号pause();while(1){sigprocmask(SIG_BLOCK,&set,NULL);mytask();//sigprocmask(SIG_UNBLOCK,&set,NULL);//pause();sigsuspend(&set2);}printf("After pause\n");
}

运行结果

linux@linux:~/Desktop$ ./pause 
^CHandle:I get sig=2         //1次CTRL+C
mytask:start  
mytask:end
^CHandle:I get sig=2         //1次CTRL+C
mytask:start
mytask:end
^CHandle:I get sig=2         //1次CTRL+C
mytask:start
^Cmytask:end                 //任务中途的1次CTRL+C
Handle:I get sig=2           //也被获取到并执行了
mytask:start
mytask:end

相关文章:

lv5 嵌入式开发-10 信号机制(下)

目录 1 信号集、信号的阻塞 2 信号集操作函数 2.1 自定义信号集 2.2 清空信号集 2.3 全部置1 2.4 将一个信号添加到集合中 2.5 将一个信号从集合中移除 2.6 判断一个信号是否在集合中 2.7 设定对信号集内的信号的处理方式(阻塞或不阻塞) 2.8 使进程挂起&#xff08;…...

【postgresql】 ERROR: multiple assignments to same column “XXX“

Cause: org.postgresql.util.PSQLException: ERROR: multiple assignments to same column "XXX"; bad SQL grammar []; nested exception is org.postgresql.util.PSQLException: ERROR: multiple assignments to same column "XXX"; 原因&#xff1a;or…...

一文读懂Llama 2(从原理到实战)

简介 Llama 2&#xff0c;是Meta AI正式发布的最新一代开源大模型。 Llama 2训练所用的token翻了一倍至2万亿&#xff0c;同时对于使用大模型最重要的上下文长度限制&#xff0c;Llama 2也翻了一倍。Llama 2包含了70亿、130亿和700亿参数的模型。Meta宣布将与微软Azure进行合…...

完整指南:如何使用 Node.js 复制文件

文件拷贝指的是将一个文件的数据复制到另一个文件中&#xff0c;使目标文件与源文件内容一致。Node.js 提供了文件系统模块 fs&#xff0c;通过该模块可以访问文件系统&#xff0c;实现文件操作&#xff0c;包括拷贝文件。 Node.js 中文件拷贝方法 在 Node.js 中&#xff0c;有…...

ElementUI - 主页面--动态树右侧内容管理

一.左侧动态树 1.定义组件 ①样式&数据处理 <template><el-menu class"el-menu-vertical-demo" background-color"#334157"text-color"#fff" active-text-color"#ffd04b" :collapse"collapsed" router :def…...

全国排名前三的直播公司无锋科技入驻天府蜂巢成都直播产业基地

最近&#xff0c;全国排名前三的直播公司——无锋科技&#xff0c;正式宣布入驻位于成都的天府蜂巢直播产业基地&#xff0c;这一消息引起了业内人士的高度关注。成都直播产业基地一直是中国直播产业的重要地标之一&#xff0c;其强大的技术和资源优势为众多直播公司提供了广阔…...

机器人中的数值优化|【五】BFGS算法非凸/非光滑处理

机器人中的数值优化|【五】BFGS算法的非凸/非光滑处理 往期内容回顾 机器人中的数值优化|【一】数值优化基础 机器人中的数值优化|【二】最速下降法&#xff0c;可行牛顿法的python实现&#xff0c;以Rosenbrock function为例 机器人中的数值优化|【三】无约束优化&#xff0…...

ESP32S3的MPU-6050组件移植教程

前言 &#xff08;1&#xff09;实习公司要搞ESP32BOX的驱动移植&#xff0c;所有资料自己找还是比较折磨人的现在我分享几个官方的组件移植资料&#xff1a; <1>Find the most exciting ESP-IDF components&#xff08;ESP32的官方组件都可以在里面查&#xff0c;按照他…...

excel筛选后求和

需要对excel先筛选&#xff0c;后对“完成数量”进行求和。初始表格如下&#xff1a; 一、选中表内任意单元格&#xff0c;按ctrlshiftL&#xff0c;开启筛选 二、根据“部门”筛选&#xff0c;比如选择“一班” 筛选完毕后&#xff0c;选中上图单元格&#xff0c;然后按alt后&…...

pyspark 检测任务输出目录是否空,避免读取报错

前言 在跑调度任务时候&#xff0c;有时候子任务需要依赖前置任务的输出&#xff0c;但类似读取 Parquet 或者 Orc 文件时&#xff0c;如果不判断目录是否为空&#xff0c;在输出为空时会报错&#xff0c;所以需要 check 一下&#xff0c;此外Hadoop通常在写入数据时会在目录中…...

「网页开发|前端开发|Vue」10 vuex模块化:将数据划分成不同modules分别管理

本文主要介绍如何使用vuex的modules将状态数据根据不同模块进行划分并分别管理以及如何使用mapGetters快速将状态管理中的数据导入成local变量。 文章目录 本系列前文传送门一、场景说明二、使用modules划分不同模块三、使用Getters获取状态管理数据Getter传参mapGetters 辅助…...

苹果CMS插件-苹果CMS全套插件免费

网站内容的生成和管理对于网站所有者和内容创作者来说是一个挑战。有一些强大的工具可以帮助您轻松地解决这些问题。苹果CMS插件自动采集插件、采集发布插件以及采集伪原创发布插件&#xff0c;是这些工具之一。它们不仅可以极大地节省您的时间和精力&#xff0c;还可以提高您网…...

域环境介绍

一、概述 内网也指局域网&#xff0c;指的是某个区域由多台计算机互连而成的计算机组&#xff0c;范围通常在数千米以内&#xff0c;在局域网中&#xff0c;可以实现文件管理&#xff0c;应用软件共享&#xff0c;打印机共享、工作组内的日程安排、电子邮件和传真通信服务等&a…...

地球同步静止轨道上的中国卫星

3万6千公里地球同步静止轨道上的中国控制的卫星&#xff08;包括香港属非国产平台卫星、外国属中国平台卫星&#xff09;&#xff0c;共80颗&#xff1b;截止到2023年8月3日&#xff0c;共有563颗在轨卫星。 号定位名称发射时间用途重量1141.1W中星1C(FH2C)2015.12.10DFH4平台…...

HAProxy代理TCP(使用HAProxy 为TiDB-Server 做负载均衡)

目录 一、使用HAProxy 为TiDB-Server 做负载均衡环境1、创建文件夹2、配置haproxy.cfg3、创建 docker-compose.yaml 文件haproxy.cfg 配置说明[参照官方文档](https://pingcap.com/docs-cn/v3.0/reference/best-practices/haproxy/ "参照官方文档") 一、使用HAProxy …...

全新自适应导航网模板 导航网系统源码 网址导航系统源码 网址目录网系统源码

高价值目录网导航网整站源码 | 2999元价值,最新版本源码下载推荐 1、导航网一键获取目标站SEO信息,7.5版本增加会员中心一键获取网站信息网站权重,增加小程序提交发布,全新自适应模板; 2、可设置游客提交、游客提交人工审核,会员免审提交,会员提交人工审核,VIP会员免…...

无人直播间

失败&#xff01;&#xff01; 采用 ffmpeg 技术进行推流 推流代码&#xff1a; 【需要将rtmp替换为你的推流地址】 ffmpeg -re -stream_loop -1 -i "rain.mp4" -c copy -f flv ""推流地址获取 以哔哩哔哩为例 点击下方链接 开播设置 - 个人中心 - …...

Linux 服务器防止 ssh 暴力密码登录破解之使用 fail2ban

前言&#xff0c;网络安全越来越重要&#xff0c;如何保证网站安全至关重要&#xff0c;在使用 Linux 服务器时&#xff0c;如果未设置有效安全登录屏障&#xff0c;每日将会有数百甚至数万次的密码暴力尝试登录&#xff0c;本篇章将介绍两种 Linux 登录安全防护 一&#xff1…...

第十四届蓝桥杯大赛软件赛决赛 C/C++ 大学 B 组 试题 D: 合并数列

[蓝桥杯 2023 国 B] 合并数列 【问题描述】 小明发现有很多方案可以把一个很大的正整数拆成若干正整数的和。他采取了其中两种方案&#xff0c;分别将他们列为两个数组 { a 1 , a 2 , ⋯ a n } \{a_1, a_2, \cdots a_n\} {a1​,a2​,⋯an​} 和 { b 1 , b 2 , ⋯ b m } \{b…...

ChatGPT必应联网功能正式上线

今日凌晨发现&#xff0c;ChatGPT又支持必应联网了&#xff01;虽然有人使用过newbing这个阉割版的联网GPT4&#xff0c;但官方版本确实更加便捷好用啊&#xff01; 尽管 ChatGPT 此前已经展现出了其他人工智能模型无可比拟的智能&#xff0c;但由于其训练数据的限制&#xff…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...

简约商务通用宣传年终总结12套PPT模版分享

IOS风格企业宣传PPT模版&#xff0c;年终工作总结PPT模版&#xff0c;简约精致扁平化商务通用动画PPT模版&#xff0c;素雅商务PPT模版 简约商务通用宣传年终总结12套PPT模版分享:商务通用年终总结类PPT模版https://pan.quark.cn/s/ece1e252d7df...

十二、【ESP32全栈开发指南: IDF开发环境下cJSON使用】

一、JSON简介 JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;具有以下核心特性&#xff1a; 完全独立于编程语言的文本格式易于人阅读和编写易于机器解析和生成基于ECMAScript标准子集 1.1 JSON语法规则 {"name"…...