lv5 嵌入式开发-9 信号机制(上)
目录
1 信号机制
2 信号的产生
3 常用信号
4 相关命令
4.1 信号相关命令 kill / killall
4.2 信号发送 – kill / raise
4.3 定时器函数相关函数 – alarm /ualarm/ pause
4.4 信号捕捉:设置信号响应方式 – signal /sigaction,闹钟实现
4.5 子进程结束信号(使用SIGCHLD信号实现回收子进程)
4.6 练习
掌握:信号机制、常用信号、信号相关命令、信号发送、定时器、信号捕捉、信号集和信号屏蔽
1 信号机制
信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式。
linux内核通过信号通知用户进程,不同的信号类型代表不同的事件
Linux对早期的unix信号机制进行了扩展
进程对信号有不同的响应方式:
- 缺省方式
- 忽略信号
- 捕捉信号
2 信号的产生
- 按键产生
- 系统调用函数产生(比如raise, kill)
- 硬件异常
- 命令行产生 (kill)
- 软件条件(比如被0除,访问非法内存等)
3 常用信号
SIGCHLD 子进程 状态改变发给父进程的
4 相关命令
4.1 信号相关命令 kill / killall
kill [-signal] pid
默认发送SIGTERM
-sig 可指定信号
pid 指定发送对象
示例:
killall [-u user | prog]
prog 指定进程名
user 指定用户名
4.2 信号发送 – kill / raise
#include <unistd.h>
#include <signal.h>
int kill(pid_t pid, int sig);
功能:发送信号
参数:
pid: > 0:发送信号给指定进程
= 0:发送信号给跟调用kill函数的那个进程处于同一进程组的进程。
< -1: 取绝对值,发送信号给该绝对值所对应的进程组的所有组员。
= -1:发送信号给,有权限发送的所有进程。
signum:待发送的信号
int raise(int sig); //给自己发信号
给自己发信号,等价于kill(getpid(), signo);
示例
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
int main(){// kill(24149,11); //对进程24149,发送一个段错误信号,进程24149接收到信号报错结束raise(11); //对自己的进程,发送一个段错误信号
}
4.3 定时器函数相关函数 – alarm /ualarm/ pause
int alarm(unsigned int seconds);
功能:定时发送SIGALRM给当前进程(一次性)
返回值:成功时返回上个定时器的剩余时间,失败时返回EOF
参数:seconds 定时器的时间
一个进程中只能设定一个定时器,时间到时产生SIGALRM
示例
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
int main(){alarm(3);while(1);
}//运行结果
linux@linux:~/Desktop$ ./alarm
Alarm clock
重复性闹钟函数
useconds_t ualarm(useconds_t usecs, useconds_t interval); (循环发送)
以useconds为单位,第一个参数为第一次产生时间,第二个参数为间隔产生
发送alarm信号函数
int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);struct itimerval {struct timeval it_interval; // 闹钟触发周期struct timeval it_value; // 闹钟触发时间
};struct timeval {time_t tv_sec; /* seconds */suseconds_t tv_usec; /* microseconds */
};
功能:定时的发送alarm信号
参数:
-which:
ITIMER_REAL:以逝去时间递减。发送SIGALRM信号
ITIMER_VIRTUAL: 计算进程(用户模式)执行的时间。 发送SIGVTALRM信号
ITIMER_PROF: 进程在用户模式(即程序执行时)和核心模式(即进程调度用时)均计算时
间。 发送SIGPROF信号
-new_value: 负责设定 timout 时间
-old_value: 存放旧的timeout值,一般指定为NULL
int pause(void);
进程一直阻塞,直到被信号中断
被信号中断后返回-1,errno为EINTR
示例:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {alarm(3);pause();printf(“I have been waken up!\n”);return 0;
}
$ ./a.out
Alarm clock重要:alarm经常用于实现超时检测
4.4 信号捕捉:设置信号响应方式 – signal /sigaction,闹钟实现
信号捕捉过程:
- 定义新的信号的执行函数handle。
- 使用signal/sigaction 函数,把自定义的handle和指定的信号相关联。
signal函数
typedef void (*sighandler_t)(int);
//它使用了typedef关键字定义了一个名为sighandler_t的新类型,这个类型是一个指向函数的指针,该函数以一个整型参数作为信号值,返回值类型为void(即不返回任何值)。通过这个定义,可以方便地声明和使用信号处理函数,以对接收到的信号做出相应的处理。sighandler_t signal(int signum, sighandler_t handler);
功能:捕捉信号执行自定义函数
返回值:成功时返回原先的信号处理函数,失败时返回SIG_ERR
参数:
- signo 要设置的信号类型
- handler 指定的信号处理函数: SIG_DFL代表缺省方式;SIG_IGN 代表忽略信号;
示例
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <linux/posix_types.h>typedef void (*sighandler_t)(int);sighandler_t oldact;void handle(int sig){printf("I cath the SIGINT \n");signal(SIGINT,oldact); //改回原先的信号处理,如按ctrl+c结束进程
}int main(){oldact = signal(SIGINT,handle);while(1){sleep(1);} }
sigaction函数
系统建议使用sigaction函数,因为signal在不同类unix系统的行为不完全一样。
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
参数说明:
signum
:要设置或获取处理方式的信号编号。act
:指向struct sigaction
结构体的指针,用于设置新的处理方式。如果为NULL
,则不会改变原有的处理方式。oldact
:指向struct sigaction
结构体的指针,在函数返回时用于存储旧的处理方式。如果为NULL
,则不会保存旧的处理方式。
struct sigaction
结构体定义如下:
struct sigaction {void (*sa_handler)(int);void (*sa_sigaction)(int, siginfo_t *, void *);sigset_t sa_mask;int sa_flags;void (*sa_restorer)(void);
}
sigaction
结构体的字段解释如下:
sa_handler
:是一个函数指针,用于指定信号处理函数,表示简单的信号处理。sa_sigaction
:是一个函数指针,用于指定信号处理函数,表示复杂的信号处理。
它有三个参数,可以获得关于信号的更详细的信息。
sa_flags参考值如下:
SA_SIGINFO:使用 sa_sigaction 成员而不是 sa_handler 作为信号处理函数
SA_RESTART:使被信号打断的系统调用自动重新发起。
SA_RESETHAND:信号处理之后重新设置为默认的处理方式。
SA_NODEFER:使对信号的屏蔽无效,即在信号处理函数执行期间仍能发出这个信号。
sa_mask
:用于设置在处理当前信号时要阻塞的信号集。sa_flags
:用于设置一些标志位,例如SA_RESTART
表示在被信号中断的系统调用重新启动。/通过将其设置为0,表示不使用任何额外的标志位,即默认行为。sa_restorer
:保留字段,已不再使用。
函数返回值:
- 成功:返回0,并将旧的信号处理方式保存到
oldact
中(如果oldact
不为NULL
)。 - 失败:返回-1,并设置
errno
来指示错误的原因。
通过调用 sigaction
函数,可以为指定的信号设置新的处理方式,或者获取当前的处理方式。这在编写信号处理程序时非常有用,以便对信号进行正确的处理和响应。
示例:定时器的实现(使用alarm)
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <linux/posix_types.h>typedef void (*sighandler_t)(int);sighandler_t oldact;void handle(int sig){if(sig == SIGINT){printf("I cath the SIGINT \n");}else if (sig==SIGALRM){printf("second timer \n");alarm(1);}// signal(SIGINT,oldact);
}int main(){struct sigaction act;act.sa_handler = handle;act.sa_flags = 0;sigemptyset(&act.sa_mask);sigaction(SIGINT,&act,NULL);alarm(1);sigaction(SIGALRM,&act,NULL);
// oldact = signal(SIGINT,handle);while(1){sleep(1);}}
示例:定时器的实现(settimer实现)
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <linux/posix_types.h>
#include <sys/time.h>typedef void (*sighandler_t)(int);sighandler_t oldact;void handle(int sig){if(sig == SIGINT){printf("I cath the SIGINT \n");}else if (sig==SIGALRM){printf("second timer \n");
// alarm(1);}// signal(SIGINT,oldact);
}int main(){struct sigaction act;act.sa_handler = handle;act.sa_flags = 0;sigemptyset(&act.sa_mask);
// sigaction(SIGINT,&act,NULL);
// alarm(1);struct itimerval timevalue;timevalue.it_interval.tv_sec = 1;timevalue.it_interval.tv_usec = 0;timevalue.it_value.tv_sec = 5;timevalue.it_value.tv_usec = 0;setitimer(ITIMER_REAL,&timevalue, NULL);sigaction(SIGALRM,&act,NULL);
// oldact = signal(SIGINT,handle);while(1){// sleep(1); //sleep也是用alarm实现的}}
示例
// 头文件省略
void handler (int signo) {if (signo == SIGINT) {printf(“I have got SIGINT!\n”); }if (signo == SIGQUIT) {printf(“I have got SIGQUIT\n”); }
}int main() {signal(SIGINT, handler);signal(SIGQUIT, handler);while ( 1 ) pause();return 0;
}
4.5 子进程结束信号(使用SIGCHLD信号实现回收子进程)
SIGCHLD的产生条件
1子进程终止时
2子进程接收到SIGSTOP信号停止时
3子进程处在停止态,接受到SIGCONT后唤醒时
SIGCHLD
可以用来处理子进程退出的僵尸
之前是使用wait来回收,现在使用信号来配合wait回收,解决父进程阻塞的问题
示例:
#include <stdio.h>
#include <signal.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>void handle(int sig){wait(NULL);printf("Get sig =%d\n",sig);}int main(){pid_t pid;struct sigaction act;act.sa_handler = handle;act.sa_flags = 0;sigemptyset(&act.sa_mask);pid = fork();if(pid>0){//wait(NULL); //利用信号处理,可以让父进程异步操作,接着干自己的事情而不阻塞sigaction(SIGCHLD,&act,NULL);while(1){printf("this is father process\n");sleep(1);}}else if(pid==0){sleep(5);exit(0);}}
执行完通过ps 命令查看,没有僵尸进程。
4.6 练习
实现捕捉SIGINT信号,在屏幕上打印 "Ctrl + c"
#include <stdlib.h>
#include <string.h>
#include <linux/posix_types.h>typedef void (*sighandler_t)(int);sighandler_t oldact;void handle(int sig){printf("Ctrl+C\n");//signal(SIGINT,oldact); //改回原先的信号处理,按ctrl+c结束进程
}int main(){oldact = signal(SIGINT,handle);while(1){sleep(1);} }
相关文章:
lv5 嵌入式开发-9 信号机制(上)
目录 1 信号机制 2 信号的产生 3 常用信号 4 相关命令 4.1 信号相关命令 kill / killall 4.2 信号发送 – kill / raise 4.3 定时器函数相关函数 – alarm /ualarm/ pause 4.4 信号捕捉:设置信号响应方式 – signal /sigaction,闹钟实现 4.5 子…...
460. LFU 缓存
请你为 最不经常使用(LFU)缓存算法设计并实现数据结构。 实现 LFUCache 类: LFUCache(int capacity) - 用数据结构的容量 capacity 初始化对象int get(int key) - 如果键 key 存在于缓存中,则获取键的值,否则返回 -1…...
YOLOV8 C++ opecv_dnn模块部署
废话不多说:opencv>4.7.0 opencv编译不做解释,需要的话翻看别的博主的编译教程 代码饱含V5,V7,V8部署内容 头文件yoloV8.h #pragma once #include<iostream> #include<opencv2/opencv.hpp> using namespace std; using namespace cv; using name…...
STM32 DMA从存储器发送数据到串口
1.任务描述 (1)ds18b20测量环境温度存储到存储器(数组)中。 (2)开启DMA将数组中的内容,通过DMA发送到串口 存在问题,ds18b20读到的数据是正常的,但是串口只是发送其低…...
Flask连接数据库返回json数据
常用方法: json.dumps(字典) 将python的字典转换为json字符串json.loads(字符串) 将字符串转换为python中的字典方法一:将python字典转化为json from flask import Flask import jsonapp Flask(__name__)app.route("/index") def index():# 返回json数据的方法…...
Openresty通过Lua+Redis 实现动态封禁IP
求背景 为了封禁某些爬虫或者恶意用户对服务器的请求,我们需要建立一个动态的 IP 黑名单。对于黑名单之内的 IP ,拒绝提供服务。并且可以设置失效 1.安装Openresty(编译安装) wget https://openresty.org/download/openresty-1.…...
碎片笔记|AIGC核心技术综述
前言:AIGC全称为AI-Generated Content,直译为人工智能内容生成。即采用人工智能技术来自动生产内容。AIGC在2022年的爆发,主要是得益于深度学习模型方面的技术创新。不断涌现的生成算法、预训练模型以及多模态等技术的融合引发了AIGC的技术变…...
28385-2012 印刷机械 锁线机 学习笔记
声明 本文是学习GB-T 28385-2012 印刷机械 锁线机. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了锁线机的型式、基本参数、要求、试验方法、检验规则、标志、包装、运输与贮存。 本标准适用于用线将书帖装订成书芯的锁线机。 …...
【大规模 MIMO 检测】基于ADMM的大型MU-MIMO无穷大范数检测研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
MySQL数据库记录的删除操作与特殊字符
在数据库管理中,除了添加和修改记录之外,删除操作也是一个重要的方面。同时特殊字符序列的处理也是必不可少的一步。 本文将深入探讨如何在MySQL数据库中进行表记录的删除操作,以及如何处理特殊字符序列。将使用《三国志》游戏数据作为示例来进行解释。 文章目录 表记录的…...
什么是TypeScript
TypeScript是一个开源的编程语言,它是JavaScript的超集。它允许开发人员编写更具可靠性和高效性的代码,同时提供了强类型支持、类、接口、模块等新的特性。TypeScript的代码可以编译成纯JavaScript代码,可以在任何支持JavaScript的平台上运行…...
[docker]笔记-网络故障处理
1、同事在虚拟机上部署docker,发现电脑无法登录虚拟机了。首先ping测是通的,从我电脑继续进行登录测试发现没问题,初步判断是她电脑网络和虚拟机网络之间连接出错。 2、进行虚拟机登录查看,首先使用route -n命令查看路由…...
牛客网_HJ1_字符串最后一个单词的长度
HJ1_字符串最后一个单词的长度 原题思路代码运行截图收获 原题 字符串最后一个单词的长度 思路 从最后一个字符开始遍历,遇到第一个空格时的长度即为最后一个单词的长度 代码 #include <iostream> #include <string> using namespace std;int main…...
智算创新,美格智能助力智慧支付加速发展
9月21日,以“智算引领创新未来”为主题的紫光展锐2023泛物联网终端生态论坛在深圳举行。作为紫光展锐重要战略合作伙伴,美格智能标准模组产品线总经理郭强华、高级产品总监刘伟鹏受邀出席论坛。美格智能基于紫光展锐5G、4G、智能SoC、Cat.1 bis等芯片平台…...
常用SQL语法总结
1.库操作 1.1.创建数据库 CREATE DATABASE 语句用来创建一个新的数据库。 语法:CREATE DATABASE DatabaseName; DatabaseName 为数据库名字,它的名字必须是唯一的,不能和其它数据库重名。 1.2.删除数据库 DROP DATABASE语句用来删除已经…...
Promise击鼓传花的游戏
Promise击鼓传花的游戏 Promise系列导航前言一、学习Promise的原因二、揭开击鼓传花游戏的面纱补充小知识 Promise系列导航 1.Promise本质击鼓传花的游戏 2.Promise四式击鼓 3.Promise击鼓传花 4.Promise花落谁家知多少 前言 👨💻👨&…...
蓝桥杯每日一题2023.9.29
蓝桥杯大赛历届真题 - C&C 大学 B 组 - 蓝桥云课 (lanqiao.cn) 题目描述1 题目分析 看见有32位,我们以此为入手点, B代表字节1B 8b b代表位,32位即4个字节 (B) 1KB 1024B 1MB 1024KB (256 * 1024 * 1024) / 4 67108864 故答案…...
Spring Boot的自动装配中的@ConditionalOnBean条件装配注解在Spring启动过程中,是如何保证处理顺序靠后的
前言 为什么Spring Boot条件注解那么多,而标题中是ConditionalOnBean呢? 因为,相比之下我们用的比较多的条件装配注解也就是ConditionalOnClass、ConditionalOnBean了,而ConditionalOnClass对顺序并不敏感(说白了就是判…...
玩转数据-大数据-Flink SQL 中的时间属性
一、说明 时间属性是大数据中的一个重要方面,像窗口(在 Table API 和 SQL )这种基于时间的操作,需要有时间信息。我们可以通过时间属性来更加灵活高效地处理数据,下面我们通过处理时间和事件时间来探讨一下Flink SQL …...
【论文笔记】A Review of Motion Planning for Highway Autonomous Driving
文章目录 I. INTRODUCTIONII. CONSIDERATIONS FOR HIGHWAY MOTION PLANNINGA. TerminologyB. Motion Planning SchemeC. Specificities of Highway DrivingD. Constraints on Highway DrivingE. What Is at Stake in this Paper III. STATE OF THE ARTA. Taxonomy DescriptionB…...
YOLOv8改进算法之添加CA注意力机制
1. CA注意力机制 CA(Coordinate Attention)注意力机制是一种用于加强深度学习模型对输入数据的空间结构理解的注意力机制。CA 注意力机制的核心思想是引入坐标信息,以便模型可以更好地理解不同位置之间的关系。如下图: 1. 输入特…...
2023年10月腾讯云优惠活动汇总:腾讯云最新优惠、代金券整理
腾讯云作为国内领先的云服务提供商,致力于为用户提供优质、稳定的云服务。为了更好地满足用户需求,腾讯云推出了各种优惠活动。本文将给大家分享腾讯云最新优惠活动,帮助用户充分利用腾讯云提供的优惠。 一、腾讯云优惠券领取【点此领取】 腾…...
BUUCTF reverse wp 65 - 70
[SWPU2019]ReverseMe 反编译的伪码看不明白, 直接动调 这里显示"Please input your flag", 然后接受输入, 再和32进行比较, 应该是flag长度要求32位, 符合要求则跳转到loc_E528EE分支继续执行 动调之后伪码可以读了 int __cdecl main(int argc, const char **arg…...
xorm数据库操作之Join、Union
golang的数据库操作xorm使用起来非常方便,不用再自己写SQl语句,而且xorm自己给我们做了SQL防注入等操作,用起来既方便又安全。此次文章我不会记录xorm的基本操作,我值记录一些特殊用法问题,包括动态创建表单、基于xorm…...
排序:基数排序算法分析
1.算法思想 假设长度为n的线性表中每个结点aj的关键字由d元组 ( k j d − 1 , k j d − 2 , k j d − 3 , . . . , k j 1 , k j 0 ) (k_{j}^{d-1},k_{j}^{d-2},k_{j}^{d-3},... ,k_{j}^{1} ,k_{j}^{0}) (kjd−1,kjd−2,kjd−3,...,kj1,kj0)组成, 其中&am…...
用go实现http服务端和请求端
一、概述 本文旨在学习记录下如何用go实现建立一个http服务器,同时构造一个专用格式的http客户端。 二、代码实现 2.1 构造http服务端 1、http服务处理流程 基于HTTP构建的服务标准模型包括两个端,客户端(Client)和服务端(Server)。HTTP 请求从客户端…...
幂级数和幂级数的和函数有什么关系?
幂级数和幂级数的和函数有什么关系? 本文例子引用自:80_1幂级数运算,逐项积分、求导【小元老师】高等数学,考研数学 求幂级数 ∑ n 1 ∞ 1 n x n \sum\limits_{n1}^{\infty}\frac{1}{n}x^n n1∑∞n1xn 的和函数 ÿ…...
Git多账号管理通过ssh 公钥的方式,git,gitlab,gitee
按照目前国内访问git,如果不科学上网,我们很大可能访问会超时。基于这个,所以我现在的git 配置已经增加到了3个了 一个公司gitlab,一个git,一个gitee. 以下基于这个环境,我们来说明下如何创建配置ssh公钥。…...
在nodejs常见的不良做法及其优化解决方案
在nodejs常见的不良做法及其优化解决方案 当涉及到在express和nodejs中开发应用程序时。遵循最佳实践对于确保项目的健壮性、可维护性和安全性至关重要。 在本文中,我们将探索开发人员经常遇到的几种常见的错误做法,并通过代码示例研究优化的最佳做法&…...
关于layui upload上传组件上传文件无反应的问题
最近使用layui upload组件时,碰到了上传文件无反应的问题,感到非常困惑。 因为使用layui upload组件不是一次两次了,之前每次都可以,这次使用同样的配方,同样的姿势,为什么就不行了呢? 照例先…...
电子商城开发网站建设/百度号注册官网
构建百万访问量电子商务网站之LVS负载均衡(前端四层负载均衡器)[连载之电子商务系统架构] 版本:V1 出处:http://jimmyli.blog.51cto.com/我站在巨人肩膀上Jimmy Li 作者:Jimmy Li 关键词:电子商务,系统架构,…...
深圳 网站 设计/推广网页
在某一次面试中,面试官问了我一个问题,他说,String str “1234”;如何在不使用 JDK自带方法的情况下,转换成 int i “123”。当时想法思路都有了,但是没写出来...... 本篇将讲述一下 String 与 int 两者之…...
南京哪家做网站好/为什么中国禁止谷歌浏览器
Spring boot maven 搭建框架 Spring Boot: 目的:这个框架帮助开发者更容易地创建基于Spring的应用程序和服务,使得pring开发者能够最快速地获得所需要的Spring功能。 优点:完全不需要XML配置,让spring应用从配置到运行…...
去年做啥网站能致富/成都电脑培训班零基础
英文原文:11 Best Practices for Low Latency Systems 自从Google发布额外的一个500ms延迟将减少20%的流量以及亚马逊发现额外的100ms延迟会使销售量下降1%已经8年了。此后,开发者们一直奋战在延迟曲线的底部,甚至前端开发者们都在压缩JavaSc…...
网站设计 导航条/西安网站seo诊断
Prometheus是继Kubernetes后第2个正式加入CNCF基金会的项目,容器和云原生领域事实的监控标准解决方案。在这次分享将从Prometheus的基础说起,学习和了解Prometheus强大的数据处理能力,了解如何使用Prometheus进行白盒和黑盒监控,以…...
wordpress缺少临时文件夹/百度网页版下载安装
备份一下手打快排的写法。 只能算是备份吧,没有解释快排的思想,以 int 为例。 没有考虑什么特殊情况,比如传入不合法指针等 /* 模仿一波 C 的 sort() 的接口* 只传排序区间的首尾指针*/ void quick_sort(int *left, int *right) {/* 枢轴值…...