Linux中sigaction函数和SIGCHLD信号的使用
sigaction函数:
函数说明:注册一个信号处理函数
函数原型:int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
函数参数:
- signum:捕捉的信号
- act:传入参数,新的处理方式
- oldact:传出参数,旧的处理方式
The sigaction structure is defined as something like:struct sigaction {void (*sa_handler)(int);//信号处理函数void (*sa_sigaction)(int, siginfo_t *, void *);sigset_t sa_mask;//信号处理函数执行期间需要阻塞的信号,信号处理函数结束后,就不阻塞了int sa_flags;//通常为0,表示默认标识void (*sa_restorer)(void);};
测试:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include <signal.h>
#include <sys/time.h>
void handler(int signo)
{printf("signo==[%d]\n",signo);sleep(5);
}
int main()
{//int sigaction(int signum, const struct sigaction *act,// struct sigaction *oldact);struct sigaction act;act.sa_handler=handler;sigemptyset(&act.sa_mask);把set信号集全部置0,不阻塞任何信号act.sa_flags=0;sigaction(SIGINT,&act,NULL);while(1){sleep(1);}return 0;
}
结果:
由结果我们可以知道在XXX信号处理函数执行期间,当XXX信号产生多次,该信号进入未决信号集中(被阻塞),在信号处理函数执行结束后,只会执行一次(信号不支持排队)。
若在sa_mask中阻塞了YYY信号,那么在XXX信号处理函数执行时,产生的YYY信号也会进入未决信号集中(被阻塞),等到XXX信号处理函数结束后执行一次。
SIGCHLD信号:
产生SIGCHLD信号的条件:
- 子进程结束的时候
- 子进程收到SIGSTOP信号
- 当子进程停止时,收到SIGCONT信号
SIGCHLLD信号的作用:
子进程退出后,内核会给它的父进程发送SIGCHLD信号,父进程收到这个信号后可以使用wait/waitpid函数对子进程进行回收。
父进程创建两个子进程,然后让父进程捕获SIGCHLD信号完成对子进程的回收
注意点:
有可能还未完成注册信号处理函数,两个子进程已经都退出了
解决方法:可以在fork之前先将SIGCHLD阻塞,当完成信号处理函数的注册后解除阻塞
当SIGCHLD信号函数处理期间,SIGCHLD信号若再次产生是被阻塞的,而且产生多次,最后只会被处理一次,这样就会产生僵尸进程
解决方法:可以在信号处理函数里面使用while(1)循环回收,这样就有可能出现捕获一次SIGCHLD信号但是回收了多个子进程的情况,从而避免产生僵尸进程
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>
#include<signal.h>
void handler(int signo)//信号处理函数
{//pid_t waitpid(pid_t pid, int *wstatus, int options);pid_t wpid;while(1)//一直死循环,防止信号处理函数执行的时候,有多个子进程终止(只会接收一次SIGCHLD信号),产生僵尸进程{wpid=waitpid(-1,NULL,WNOHANG);//设为非阻塞,因为子进程收到SIGSTOP,SIGCONT信号,也会发出SIGCHLD信号,这样一来并没有子进程终止,就会一直阻塞if(wpid>0){printf("[%d]child is quit\n",wpid);}else if(wpid==0)//还有子进程运行,break,等下一个SIGCHLD信号{break;}else if(wpid==-1)//没有子进程,已经全部回收,break{printf("no child is living\n");break;}}
}
int main()
{
//先把SIGCHLD信号阻塞,防止还没有注册信号处理函数时,就已经有SIGCHLD信号产生,被忽略sigset_t set;sigemptyset(&set);sigaddset(&set,SIGCHLD);
// int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);sigprocmask(SIG_BLOCK,&set,NULL);int i=0;for(;i<2;i++)//循环产生两个兄弟子进程{pid_t pid=fork();if(pid<0){perror("fork error");return -1;}else if(pid>0){printf("father:pid=[%d]\n",getpid());}else if(pid==0){break;}}if(i==0){printf("[%d]child:pid=[%d],fpid=[%d]\n",i,getpid(),getppid());}else if(i==1){printf("[%d]child:pid=[%d],fpid=[%d]\n",i,getpid(),getppid());}else if(i==2){struct sigaction act;act.sa_handler=handler;sigemptyset(&act.sa_mask);act.sa_flags=0;sigaction(SIGCHLD,&act,NULL);//注册信号处理函数sigprocmask(SIG_UNBLOCK,&set,NULL);//把SIGCHLD信号设置为非阻塞while(1){sleep(1);}}return 0;
}
结果:
使用信号传递让父子进程来回计数
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<signal.h>
//定义成全局变量,不然回调函数无法辨认
int num=0;//从0开始计数
int flag=0;//开关变量
void func1(int signo)//父进程的信号处理函数
{printf("f:[%d]\n",num);num+=2;flag=0;sleep(1);
}
void func2(int signo)//子进程的信号处理函数
{printf("c:[%d]\n",num);num+=2;flag=0;sleep(1);
}
int main()
{pid_t pid=fork();if(pid<0){perror("fork error");return -1;}else if(pid>0){signal(SIGUSR1,func1);//注册信号处理函数flag=1;//开关初始为1,让子进程先发出SIGUSR2信号给父进程while(1){if(flag==0){kill(pid,SIGUSR2);flag=1;}}}else if(pid==0){num=1;//子进程从一开始计数signal(SIGUSR2,func2);while(1){if(flag==0){kill(getppid(),SIGUSR1);flag=1;}}}
}
结果:
相关文章:
Linux中sigaction函数和SIGCHLD信号的使用
sigaction函数: 函数说明:注册一个信号处理函数 函数原型:int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); 函数参数: signum:捕捉的信号act:传入参数,…...
【MySQL】操作库 —— 表的操作 -- 详解
一、增加表 1、创建表 mysql> create database [if not exists] table_name ( -> field1 datatype, -> field2 datatype, -> field3 datatype -> ) character set 字符集 collate 校验规则 engine 存储引擎; 注意 :最后一行也可以写成&#x…...
ZigBee学习——在官方例程实现组网
✨Z-Stack版本:3.0.2 ✨IAR版本:10.10.1 ✨这篇博客是在善学坊BDB组网实验的基础上进行完善,并指出实现的过程中会出现的各种各样的问题! 善学坊教程地址: ZigBee3.0 BDB组网实验 文章目录 一、基础工程选择二、可能遇…...
ES实战--wildcard正则匹配exists过滤字段是否存在
wildcard 通配符中的 * 表示任意数量的字符 ?表示任意单个字符 #正则匹配 GET /wildcard-test/_search {"query": {"wildcard": {"title": {"wildcard": "ba*n"}}} } #响应:"hits": {"total": {"…...
C++学习:二分查找
二分查找的前提 库函数只能对数组进行二分查找。 对一个数组进行二分查找的前提是这个数组中的元素是单调的。 一般为单调不减,当然如果是单调不增也可以(需要修改比较函数) 例如: [1,5,5,9,18]是单调的 [1 , 9, 9,…...
语言与科技创新(大语言模型对科技创新的影响)
1.语言因素对科技创新的影响 科技创新中的语言因素至关重要,具体体现在以下几个方面: 科技文献交流: 英语作为全球科学研究的通用语言,极大地推动了科技成果的国际传播与合作。在国际上,科学家们在发表论文、报告研究…...
【C语言】简单贪吃蛇实现保姆级教学!!!
关注小庄 顿顿解馋૮(˶ᵔ ᵕ ᵔ˶)ა 新年快乐呀小伙伴 引言: 小伙伴们应该都有一个做游戏的梦吧?今天让小庄来用C语言简单实现一下我们的童年邪典贪吃蛇,顺便巩固我们的C语言知识,请安心食用~ 文章目录 贪吃蛇效果一.游戏前工作…...
rtt设备io框架面向对象学习-uart设备
目录 1.uart设备基类2.uart设备基类的子类3.初始化/构造流程3.1设备驱动层3.2 设备驱动框架层3.3 设备io管理层 4.总结5.使用 1.uart设备基类 此层处于设备驱动框架层。也是抽象类。 在/ components / drivers / include / drivers 下的serial.h定义了如下uart设备基类 struc…...
Innodb下修改事务工作流程(buffer pool、redo log、undolog)
1、在Buffer Pool中读取数据:当InnoDB需要更新一条记录时,首先会在Buffer Pool中查找该记录是否在内存中。如果没有在内存中,则从磁盘读取该页到Buffer Pool中。 2、记录UndoLog:在修改操作前,InnoDB会在Undo Log中记…...
redis为什么使用跳跃表而不是树
Redis中支持五种数据类型中有序集合Sorted Set的底层数据结构使用的跳跃表,为何不使用其他的如平衡二叉树、b树等数据结构呢? 1,redis的设计目标、性能需求: redis是高性能的非关系型(NoSQL)内存键值数据…...
【matalab】基于Octave的信号处理与滤波分析案例
一、基于Octave的信号处理与滤波分析案例 GNU Octave是一款开源软件,类似于MATLAB,广泛用于数值计算和信号处理。 一个简单的信号处理与滤波分析案例,说明如何在Octave中生成一个有噪声的信号,并设计一个滤波器来去除噪声。 首…...
Elasticsearch:特定领域的生成式 AI - 预训练、微调和 RAG
作者:来自 Elastic Steve Dodson 有多种策略可以将特定领域的知识添加到大型语言模型 (LLM) 中,并且作为积极研究领域的一部分,正在研究更多方法。 对特定领域数据集进行预训练和微调等方法使 LLMs 能够推理并生成特定领域语言。 然而&#…...
HarmonyOS—UI 开发性能提升的推荐方法
开发者若使用低性能的代码实现功能场景可能不会影响应用的正常运行,但却会对应用的性能造成负面影响。本章节列举出了一些可提升性能的场景供开发者参考,以避免应用实现上带来的性能劣化。 使用数据懒加载 开发者在使用长列表时,如果直接采用…...
84 CTF夺旗-PHP弱类型异或取反序列化RCE
目录 案例1:PHP-相关总结知识点-后期复现案例2:PHP-弱类型对比绕过测试-常考点案例3:PHP-正则preg_match绕过-常考点案例4:PHP-命令执行RCE变异绕过-常考点案例5:PHP-反序列化考题分析构造复现-常考点涉及资源…...
Duilib List 控件学习
这是自带的一个示例; 一开始运行的时候List中是空的,点击Search按钮以后就填充列表框; 先看一下列表框列头是在xml文件中形成的; <List name="domainlist" bkcolor="#FFFFFFFF" ... menu="true"> <ListHeader height="24…...
详细了解Node.js的配置与使用!
详细了解Node.js的配置与使用! Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。它允许开发者在服务器端运行 JavaScript,从而实现全栈 JavaScript 开发。本文将介绍 Node.js 的配置和 npm 的应用。 一、Node.js 配置 下载与安装 首先&…...
OpenCV 移动最小二乘图像变形
文章目录 一、简介二、实现代码三、实现效果参考文献一、简介 在现实生活中,我们常常应用一些刚性的变换来实现物体的旋转平移,对于非刚性的变换我们都没有在意,其实这种变换也是无处不在的,如我们经常看的动画就可以通过一些非刚性的变换达到一些非常夸张的效果。这里,我…...
【深度学习】S2 数学基础 P4 概率论
目录 基本概率论概率论公理随机变量 多个随机变量联合概率条件概率贝叶斯定理求和法则独立性 期望与方差小结 基本概率论 机器学习本质上,就是做出预测。而概率论提供了一种量化和表达不确定性水平的方法,可以帮助我们量化对某个结果的确定性程度。 在…...
跟我学c++中级篇——静态多态
一、多态 Polymorphism,多态。学习过c的人如果不知道多态,基本上就是打入c内部的C程序员了。在前边曾经对多态进行过分析,对其中的虚函数(虚表等)也进行过较为详细的说明。 多态其实非常好理解,不要硬扣书…...
设计模式--桥接模式(Bridge Pattern)
桥接模式(Bridge Pattern)是一种结构型设计模式,它主要是用于将抽象部分与实现部分分离,使它们可以独立地变化。 桥接模式主要包含以下几个角色: Abstraction(抽象类):定义抽象类的…...
统计图饼图绘制方法(C语言)
统计图饼图绘制方法(C语言) 常用的统计图有条形图、柱形图、折线图、曲线图、饼图、环形图、扇形图。 前几类图比较容易绘制,饼图绘制较难。今值此介绍饼图的绘制方法。 本方法采用C语言的最基本功能: ( 1.)…...
洛谷C++简单题小练习day12—寻找最小值小程序
day12--寻找最小值--2.16 习题概述 题目描述 给出 n 和 n 个整数 ai,求这 n 个整数中最小值是什么。 输入格式 第一行输入一个正整数 n,表示数字个数。 第二行输入 n 个非负整数,表示 1,2…a1,a2…an,以空格隔开。 …...
相机图像质量研究(13)常见问题总结:光学结构对成像的影响--鬼影
系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结:光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结:光学结构对成…...
车载诊断协议DoIP系列 —— 车辆以太网节点需求汇总
车载诊断协议DoIP系列 —— 车辆以太网节点需求汇总 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师(Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。江湖一碗茶,…...
掘根宝典之C++包含对象的类,私有继承,保护继承,三大继承方式总结
包含对象成员的类 包含,组合和层次化:一个类里面的类成员之一是个类对象 我们来看个例子 #include<iostream> using namespace std; class AA { private:int a_; public:AA(int a):a_(a){}void A(){cout << a_ << endl;} }; class …...
第六篇:MySQL图形化管理工具
经过前五篇的学习,对于数据库这门技术的理解,我们已经在心中建立了一个城堡大致的雏形,通过命令行窗口(cmd)快速上手了【SQL语法-DDL-数据定义语言】等相关命令 道阻且长,数据库技术这一宝藏中还有数不清的…...
计算机网络——12DNS
DNS DNS的必要性 IP地址标识主机、路由器但IP地址不好记忆,不便于人类用使用(没有意义)人类一般倾向于使用一些有意义的字符串来标识Internet上的设备存在着“字符串”——IP地址的转换的必要性人类用户提供要访问机器的“字符串”名称由DN…...
vue3-应用规模化-工具链
工具链 项目脚手架 Vite Vite 是一个轻量级的、速度极快的构建工具,对 Vue SFC 提供第一优先级支持。作者是尤雨溪,同时也是 Vue 的作者! 要使用 Vite 来创建一个 Vue 项目,非常简单: (推荐)…...
EasyExcel动态列导出
测试代码地址:https://gitee.com/wangtianwen1996/cento-practice/tree/master/src/test/java/com/xiaobai/easyexcel/dynamiccolumn 官方文档:https://easyexcel.opensource.alibaba.com/docs/2.x/quickstart/write 一、实现方式 1、根据需要导出的列…...
JAVA面试题11
什么是Java的访问修饰符,并列出它们的作用。 Java的访问修饰符包括public、private、protected和默认。它们的作用如下: public: 可以被任何其他类访问。 private: 只能被所在类访问,其他类无法访问。 protected: 可以被所在类和同一个包中的…...
网站区域名是什么意思/seo网络推广哪家专业
常见软件测试面试题(1)问题一:为什么要在一个团队中开展软件测试工作?任何软件在开发过程中都会留下缺陷,带有缺陷的软件产品如果提交出去,可能会给公司带来不可估量的损失,我们必须在客户之前发现尽可能多的问题&…...
此网站在美国进行维护/seo如何优化一个网站
(转)oracle的异常处理oracle提供了预定义例外、非预定义例外和自定义例外三种类型。其中预定义例外用于处理常见的oracle错误;非预定义例外用于处理预定义所不能处理的oracle错误;自定义例外处理与oracle错误无关的其他情况。Oracle代码编写过程中&#…...
山东企业网站建设/竞价推广怎样管理
整体框架 因特网概述 交换方式 计算机网络的定义和分类 性能指标 体系结构 物理层 数据链路层 网络层 运输层 应用层...
农产品电商网站建设的主要工作/百度官方网站首页
原文:http://stackoverflow.com/questions/6748996/how-to-set-custom-tick-marks-in-core-plot-to-icons Axis label 可以使用任何 CPTLayer(CALayer 子类)作为标签。用UIImage 作为 CPTLayer 的背景层即可定制轴标签。有许多Core Plot 的使…...
网站建设与维护内容/推广链接点击器网页
分析今天又遇到一个问题:怎样将文件上传到局域网内的另一台机器上。解决方案粗略的想了下大概有如下几种:1.搭建一台FTP服务器,然后通过FTP协议进行文件传输。这个方式固然有效,但是有点麻烦。2.通过Socket来传输文件,…...
手表网站模板/百度一对一解答
今天是2020年阳历的最后一天,真巧,还是我的生日,遗憾的是这年的计划没有完成,理想总是完美的,虽然考虑到自己可能写不完,但是到年底最后一天还是有些不甘。明年的任务除了明年的计划还需要补上今年的任务。…...