【Linux】信号补充与总结

news2024/11/24 20:04:15

可重入函数

分析

mian函数正在调用insert函数向链表中插入节点。insert函数分为两步,刚刚执行完第一步时此时硬件发生中断,使进程切换到内核。中断处理完毕切换到用户态之前发现有信号未决,于是进入了信号的处理函数,信号的处理函数中同样有insert操作,于是向链表中插入了一个新节点。进行完毕后返回到main函数,按照上下文接着执行main函数中insert函数的第二步,令头节点指向node1。从图中可以看出,这时候出现了一个问题,明明我们想要两个节点插入,可实际仅仅插入了一个,node2丢失了,也就是我们平常说的内存泄漏。
 

像上例这样,insert函数被不同的控制流调用,在第一次调用还没有返回时就再次进入该函数,这称为重入。如果insert访问的是一个全局链表,就可能因为重入而产生错误,这称为不可重入函数。相反,如果一个函数只访问自己的参数和局部变量,则称为可重入函数。

C语言的volatile关键字

【测试代码】

#include<stdio.h>

#include<unistd.h>
#include<signal.h>

int flag=0;

void handler(int signo)
{
    printf("捕捉到信号:%d ;",signo);
    printf("flag:0->1\n",flag);
    flag=1;
}


int main()
{
    signal(2,handler);

    while(!flag);
    printf("process noaml exti\n");
    return 0;
}

标准情况下,键入 CTRL-C ,2号信号被捕捉,执行自定义动作,修改 flag=1 , while 条件不满足,退出循环,进程退出 

优化情况下,键入 CTRL-C ,2号信号被捕捉,执行自定义动作,修改 flag=1 ,但是 while 条件依旧满足,进程继续运行!但是很明显flag肯定已经被修改了,但是为何循环依旧执行?很明显, while 循环检查的flag,并不是内存中最新的flag,这就存在了数据二异性的问题。 while 检测的flag其实已经因为优化,被放在了CPU寄存器当中。

如何解决呢?很明显需要 volatil (中文:易变的)

volatile的作用:

避免变量被写到寄存器中,就算写到内存器中,读取时也要先读取内存中的值,然后刷新到寄存器里。 

SIGCHLD信号

子进程退出,父进程是是如何知道的呢?

答:①以前:通过调用waitpid函数,阻塞或者非阻塞进行等待--都需要父进程的检测,子进程退出了,父进程不知道!

②现在:其实,子进程退出的时候,会向父进程发送SIGCHLD信号,而父进程默认的处理动作是什么都不做!

【证明子进程会向父进程发送SIGCHLD信号代码】

void handler(int signo)
{
    printf("%d:捕捉到信号:%d\n", getpid(), signo);
}

int main()
{
    signal(SIGCHLD, handler);
    pid_t id = fork();
    if (id == 0)
    {
        int cnt = 5;
        while (cnt--)
        {
            printf("我是子进程,我的pid:%d,ppid:%d\n", getpid(), getppid());
            sleep(1);
        }
        printf("子进程正常退出!\n");
        exit(0);
    }
    sleep(7);
    printf("父进程正常退出!\n");
    return 0;
}

要求:父进程很忙,编写代码让父进程不要随时检测子进程退出,让子进程退出的时候在告诉父进程要回收了!

【代码实现】


void handler(int signo)
{
    printf("%d:捕捉到信号:%d\n", getpid(), signo);
    while (1)
    {
        pid_t id = waitpid(-1, NULL, 0);
        if (id > 0)
        {
            printf("wait child id:%d\n", id);
        }
        else
            break;
    }
}

int main()
{
    signal(SIGCHLD, handler);
    for (int i = 0; i < 5; i++)
    {
        pid_t id = fork();
        if (id == 0)
        {
            int cnt = 5;
            while (cnt--)
            {
                printf("我是子进程,我的pid:%d,ppid:%d\n", getpid(), getppid());
                sleep(1);
            }
            printf("子进程正常退出!\n");
            exit(0);
        }
    }

    while (1)
        ;
    printf("父进程正常退出!\n");
    return 0;
}

父进程不想回收子进程,加入这条语句即可:signal(SIGCHLD, SIG_IGN);

 

信号总结

 

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

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

相关文章

XGBoost实例——皮马印第安人糖尿病预测和特征筛选

利用皮马印第安人糖尿病数据集来预测皮马印第安人的糖尿病&#xff0c;以下是数据集的信息&#xff1a; Pregnancies&#xff1a;怀孕次数Glucose&#xff1a;葡萄糖BloodPressure&#xff1a;血压 (mm Hg)SkinThickness&#xff1a;皮层厚度 (mm)Insulin&#xff1a;胰岛素 2…

硬件——光模块

简介 光模块的作用就是发送端把电信号转换成光信号&#xff0c;通过光纤传送后&#xff0c;接收端再把光信号转换成电信号。 常见光模块 GBIC 说明&#xff1a;已淘汰产品 速率&#xff1a;1Gbps 出现时间&#xff1a;2000年之前 SFP 说明&#xff1a;GBIC的升级 速率&…

Spring依赖注入方式,自动装配及自动装配特征

Spring依赖注入方式 一、setter注入1.1简单类型1.2引用类型&#xff08;基本数据类型与String&#xff09; 二、构造器注入1.1简单类型1.2引用类型&#xff08;基本数据类型与String&#xff09; 三、依赖注入方式选择四、自动装配依赖自动装配特征 总结 一、setter注入 依赖注…

Windows下安装Hadoop(手把手包成功安装)

Windows下安装Hadoop&#xff08;手把手包成功安装&#xff09; Windows下安装Hadoop&#xff08;手把手包成功安装&#xff09;一、环境准备1.1、查看是否安装了java环境 二、下载Hadoop的相关文件三、解压Hadoop安装包四、替换bin文件夹五、配置Hadoop环境变量六、检查环境变…

UWB自组网定位技术助力消防救援、消防训练人员定位调度!

在消防救援领域&#xff0c;保障消防人员的人身安全是头等大事&#xff01;而保障消防人员的生命安全的关键在于确认其在火场中所在的位置&#xff0c;一旦遇险&#xff0c;可以及时通知后台管理人员和现场调度人员&#xff0c;也方便管理人员及时调度周围救火人员及时援手施救…

Oracle 截取指定字符到目标串的末尾

SQL&#xff1a; SELECT-- 目标字符串 目标字符串 指定符号 最后一个 最后一个字符位置1 substr( HG/2106010103/YG\FJSJ\SXKTFJ\FJ03_JPHD, instr( HG/2106010103/YG\FJSJ\SXKTFJ\FJ03_…

嵌入式linux通用spi驱动之spidev使用总结

Linux内核集成了spidev驱动&#xff0c;提供了SPI设备的用户空间API。支持用于半双工通信的read和write访问接口以及用于全双工通信和I/O配置的ioctl接口。使用时&#xff0c;只需将SPI从设备的compatible属性值添加到spidev区动的spidev dt ids[]数组中&#xff0c;即可将该SP…

【后端面经】微服务架构( 1-4) | 降级:为什么马服要关闭所有人聊天?

文章目录 一、 前置知识1、什么是降级?2、降级的典型应用3、为什么要降级?4、降级的分类5、如何降级?A) 降级的应用场景B) 跨服务降级C) 提供有损服务二、面试环节1、面试准备2、基本流程3、亮点方案A) 读写服务降级写服务B) 快慢路径降级慢路径三、章节汇总 在熔断章…

opencv-23 图像几何变换02-翻转-cv2.flip()

在 OpenCV 中&#xff0c;图像的翻转采用函数 cv2.flip()实现 &#xff0c;该函数能够实现图像在水平方向翻转、垂直方向翻转、两个方向同时翻转&#xff0c;其语法结构为&#xff1a; dst cv2.flip( src, flipCode )式中&#xff1a;  dst 代表和原始图像具有同样大小、类…

通过RPM方式安装,升级,卸载,以及配置使用MySQL

通过RPM方式安装&#xff0c;升级&#xff0c;卸载&#xff0c;以及配置使用MySQL 一、下载 MySQL是一种开源的关系数据库管理系统&#xff0c;被广泛应用于各种业务应用中。本文将讲解如何下载和安装MySQL的rpm安装包。下载rmp安装包有多种方式&#xff1a; 1、可以到MySQL的…

【图解CAN总线】-10-详解CANFD的TDC以及SSP(收发器延迟补偿和第二采样点)

目录 1 CAN Transceiver收发器结构 1.1 CAN收发器对本ECU发送CAN报文的“回采” 1.2 什么是Loop delay环路延迟 1.2.1 Loop delay环路延迟的典型值 2 什么是TDC:Transceiver Delay Compensation收发器延迟补偿 2.1 总结&#xff1a;Transceiver Delay Compensation启用条…

【C#】.Net Framework框架使用JWT

2023年&#xff0c;第31周&#xff0c;第2篇文章。给自己一个目标&#xff0c;然后坚持总会有收货&#xff0c;不信你试试&#xff01; 本篇文章主要简单讲讲&#xff0c;.Net Framework框架下使用JWT的代码例子&#xff0c;以及他们的基本概念。 2002年微软发布了.net framewo…

读书会-《博弈论究竟是什么》

一. 什么是博弈论&#xff1f; 博弈即一些个人、队组或其他组织&#xff0c;面对一定的环境条件&#xff0c;在一定的规则下&#xff0c;同时或先后&#xff0c;一次或多次&#xff0c;从各自允许选择的行为或策略中进行选择并加以实施&#xff0c;各自取得相应结果的过程。 博…

re学习(25)i春秋-re-basebasebase(base64+函数构造)

参考文章&#xff1a;re学习笔记&#xff08;22&#xff09;爱春秋CTF答题夺旗赛&#xff08;第四季&#xff09;-re-basebasebase_ctfbase~base_Forgo7ten的博客-CSDN博 总结&#xff1a;1.flag——→base64加密&#xff08;自定义&#xff09;——→与3异或——→加密后数据…

spring启动流程 (6完结) springmvc启动流程

SpringMVC的启动入口在SpringServletContainerInitializer类&#xff0c;它是ServletContainerInitializer实现类(Servlet3.0新特性)。在实现方法中使用WebApplicationInitializer创建ApplicationContext、创建注册DispatcherServlet、初始化ApplicationContext等。 SpringMVC…

大数据Flink(五十):流式计算简介

文章目录 流式计算简介 一、数据的时效性 二、流式计算和批量计算

dubbo概论

目录 前言&#xff1a; 1.概述 2.服务发现 3.容错 3.1.注册中心宕机 3.2.负载均衡 3.3.限流、熔断 4.通信协议 4.1.HTTP 4.2.dubbo 5.总结 前言&#xff1a; 这可能是全网最深入浅出的dubbo文章&#xff0c;如果你会spring cloud&#xff0c;恭喜你&#xff0c;你可…

Zookeeper命令总结

目录 1、常用命令2、ls path3、create xxx创建持久化节点创建临时节点创建持久化序列节点 4、get path5、set path6、delete path7、监听器总结1&#xff09;节点的值变化监听2&#xff09;节点的子节点变化监听&#xff08;路径变化&#xff09;3&#xff09;当某个节点创建或…

Maven基础之项目创建、packaging

文章目录 创建 maven 项目流程骨架是浮云&#xff0c;packaging 是关键 创建 maven 项目流程 通过骨架&#xff08;archetype&#xff09;创建 maven 工程 第一步&#xff1a;选择 new → maven → Maven Project 第二步&#xff1a;New Maven Project 窗口不作任何设置&…

【软件测试】基于博客系统的自动化测试

目录 1.我的博客系统链接 2.使用selenium对博客系统进行自动化测试 1.引入依赖 2.创建公共类 3.创建测试套件类 4.测试登陆界面 5. 测试博客列表页 6.测试写博客页面 7.测试删除博客 8.最终运行结果 1.我的博客系统链接 用户登录 2.使用selenium对博客系统进行自动…