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

初识Linux · 信号处理 · 续

目录

前言:

可重入函数

重谈进程等待和优化


前言:

在前文,我们已经介绍了信号产生,信号保存,信号处理的主题内容,本文作为信号处理的续篇,主要是介绍一些不那么重要的内容,第一个点是可重入函数,第二个点是在信号处理这里的进程等待。

那么话不多说,我们进入主题吧!


可重入函数

大家对于链表的增删查改已经是什么熟悉了吧?在Linux中,如果我们有一个链表,我们要对链表执行的操作是insert,那么从main函数进去之后,进行p->next这步的时候突然进行信号捕捉的话,这里肯定有人会有疑问的了,为什么会进行信号捕捉呢

如果是这个进程的时间片到了呢?OS要调度其他的进程了,那么从用户态转到了内核态,此时进行信号的捕捉,所以捕捉到了信号,就又会插入节点,原本插入的节点是Node1的,这下多出来了一个Node2节点,可是我们甚至没有办法去调用node2节点,这造成的问题是什么呢?

造成的问题是十分严重的,即内存泄漏

那么这种函数,会造成内存泄漏,或者说是涉及到了共享资源的,比如堆的开辟,比如全局变量,比如静态变量都是共享的,涉及到了以上共享资源的函数,就不满足可重入性

那么我们应该如何实现具备可重入性的函数呢?

  1. 不使用全局或静态变量:因为全局或静态变量是共享的,多个线程同时访问可能会导致数据不一致。如果必须使用,则必须通过适当的同步机制(如互斥锁)来保护这些变量。

  2. 不调用不可重入的函数:如果一个函数调用了另一个不可重入的函数,那么它本身也会变成不可重入的。

  3. 不返回指向静态分配的内存的指针:因为这可能导致多个线程返回相同的指针,从而访问和修改相同的内存区域。

  4. 不使用任何依赖于特定线程环境的资源:例如,某些I/O操作(如标准输入/输出)可能依赖于特定的线程环境,如果它们不是线程安全的,那么调用这些操作的函数就不是可重入的。

其实方式很简单,我们只需要保证该函数没有使用共享资源即可,反例是stl里面的容器,几乎所有的容器都涉及到了堆上的开辟,比如扩容等操作,那么这些所有函数就不是可重入的。

这个点我们了解一下即可。


重谈进程等待和优化

有人好奇咯,这里明明介绍的是信号,和进程等待有什么关系呢?这里更厉害的其实还有涉及到了编译器的优化方面,并且编译器优化也分为了几个层次,我们先从进程等待入手。

我们先看一段代码:

int gflag = 0;void changedata(int signo)
{std::cout << "get a signo:" << signo << ", change gflag 0->1" << std::endl;gflag = 1;
}int main() // 没有任何代码对gflag进行修改!!!
{signal(2, changedata);while(!gflag); // while不要其他代码std::cout << "process quit normal" << std::endl;
}

可以发现发送2号信号之后,发现gflag确实是从0变成了1,不然while循环也是不能结束的。

好了,现在我们来谈谈编译器优化的问题,在C++里,连续的拷贝构造 + 构造,编译器是直接会优化成直接构造的,这个我们是十分清楚的。

那么,g++也是个编译器吧?它也会进行相应的优化,我们先man一下g++:

这一行代表的优化成都,默认的优化是O0,我们也可以在编译的时候修改优化程度,可是我们光是知道优化是没有用的,我们还需要介绍一下上面代码的硬件部分知识:

对于cpu来说,它执行的运算一般是分为逻辑运算和算数运算的,对于上面while里面的判断,执行的就是逻辑运算,不管是哪种运算,将值放到寄存器的时候,都是从物理内存里面放吧?

好,现在是cpu从物理内存里面得到对应的数据,当然这个过程是由OS来完成的,那么,每次都要从物理内存拿这个数据是不是有点麻烦OS了?所以编译器在这里如果开了优化,那么就不让cpu从物理内存里面获取gflag的值了,直接就让cpu从寄存器里面获取,也就是说,从运行函数开始,寄存器里面只有一个值,也就是第一次while判断里的gflag的值,那么也就代表,我们即便是修改了gflag的值,cpu也不知道,因为它只从寄存器里面读取:

将对应的makefile修改一下,然后我们试试:

发现的现象是,嘿!退不出去了,也就印证了编译器在这里的优化。

这种现象叫做没有保持内存的可见性。

那么我们如何保持内存的可见性呢?很简单,只需要用到一个关键字就可以了,volatile即可,这个在const部分我们也有使用该国,这里加一个关键字的事儿,所以就不过多演示了。


好了,现在我们来谈谈进程的等待。

我们知道,父进程一般是会等待子进程的吧?并且父进程要收集子进程的退出信息吧?

可是父进程怎么知道子进程什么时候退出呢?

实际上,子进程退出的时候,是会给父进程发送相关信号的,该信号是SIGCHLD:

该信号是对应的17号信号。

默认的行为其实是Ign,也就是忽略的意思。

void notice(int signo)
{std::cout << "get a signal: " << signo << " pid: " << getpid() << std::endl;pid_t rid = waitpid(-1, nullptr, 0);if (rid > 0){std::cout << "wait child success, rid: " << rid << std::endl;}else if (rid < 0){std::cout << "wait child success done " << std::endl;}
}
void DoOtherThing()
{std::cout << "DoOtherThing~" << std::endl;
}
int main()
{signal(SIGCHLD, notice);pid_t id = fork();if (id == 0){std::cout << "I am child process, pid: " << getpid() << std::endl;sleep(3);exit(1);}// fatherwhile (true){DoOtherThing();sleep(1);}return 0;
}

对于上面的代码是我们信号处理部分熟知的,我们通过这个代码,验证了子进程退出的时候的的确确会发送17号信号,可是我们在信号处理的时候也知道了,信号如果还没有处理完,是会自动屏蔽当前多出来的信号的,也就是我们创建多个子进程的事儿:

    for (int i = 0; i < 10; i++){pid_t id = fork();if (id == 0){std::cout << "I am child process, pid: " << getpid() << std::endl;sleep(3);exit(1);}}

做了以上的修改之后,我们发现:

创建子进程之后,父进程等待子进程是一个一个等待的,这也验证了之前所说的,信号被屏蔽之后,会继续处理被屏蔽的信号。

那么,你说有没有进程是一直不退出的呢?如果创建了一个永远不退出的子进程怎么办?假设这里存在5个要退出的子进程,5个不知道是否退出的子进程,难道父进程要一个一个的问你是否要退出吗?

这是不现实的,如果父进程真的傻傻的去等待了,导致的结果就是两个进程永远退出不了,只能被系统回收。因为造成了阻塞,所以,我们可以将等待方式设置一下,变成非阻塞等待:

void notice(int signo)
{std::cout << "get a signal: " << signo << " pid: " << getpid() << std::endl;while (true){pid_t rid = waitpid(-1, nullptr, WNOHANG); // 阻塞啦!!--> 非阻塞方式if (rid > 0){std::cout << "wait child success, rid: " << rid << std::endl;}else if (rid < 0){std::cout << "wait child success done " << std::endl;break;}else{std::cout << "wait child success done " << std::endl;break;}}
}

并且,当我们对于17号信号设置成了忽略,子进程也不会出现僵尸问题了。

以上是对于信号处理的补充。


感谢阅读!

相关文章:

初识Linux · 信号处理 · 续

目录 前言&#xff1a; 可重入函数 重谈进程等待和优化 前言&#xff1a; 在前文&#xff0c;我们已经介绍了信号产生&#xff0c;信号保存&#xff0c;信号处理的主题内容&#xff0c;本文作为信号处理的续篇&#xff0c;主要是介绍一些不那么重要的内容&#xff0c;第一个…...

【Linux】虚拟地址空间,页表,物理内存

目录 进程地址空间&#xff0c;页表&#xff0c;物理内存 什么叫作地址空间&#xff1f; 如何理解地址空间的区域划分&#xff1f; 地址空间结构体 为什么要有地址空间&#xff1f; 页表 cr3寄存器 权限标记位 位置标记位 其他 每个存储单元是一个字节&#xff0c;一…...

C++ 并发专题 - 线程安全的单例模式

一&#xff1a;概述&#xff1a; 在C编程中&#xff0c;call_once 是一种机制&#xff0c;用于确保某个函数或代码段在多线程环境下仅被调用一次。这种机制常用于初始化资源、配置全局变量或执行只需执行一次的逻辑。在 C11 标准中&#xff0c;std::call_once 是由标准库提供的…...

Spring Boot汽车世界:资讯与技术的交汇

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…...

力扣 LeetCode 541. 反转字符串II(Day4:字符串)

解题思路&#xff1a; i可以成段成段的跳&#xff0c;而不是简单的i class Solution {public String reverseStr(String s, int k) {char[] ch s.toCharArray();// 1. 每隔 2k 个字符的前 k 个字符进行反转for (int i 0; i < ch.length; i 2 * k) {// 2. 剩余字符小于 …...

Django5 2024全栈开发指南(一):框架简介、环境搭建与项目结构

目录 一、Python Web框架要点二、Django流程2.1 Django介绍2.1.1 简介2.1.2 特点2.1.3 MVT模式2.1.4 Django新特性2.1.5 Django学习资料 2.2 搭建Django框架开发环境2.2.1 安装Python语言环境2.2.2 安装Django框架 2.3 创建Django项目2.4 Pycharm创建项目2.5 初试Django52.5.1 …...

Uniapp运行环境判断和解决跨端兼容性详解

Uniapp运行环境判断和解决跨端兼容性 开发环境和生产环境 uniapp可通过process.env.NODE_ENV判断当前环境是开发环境还是生产环境&#xff0c;一般用于链接测试服务器或者生产服务器的动态切换。在HX中&#xff0c;点击运行编译出来的代码是开发环境&#xff0c;点击发行编译…...

Linux设置开机自动执行脚本 rc-local

使用/etc/rc.local 1、启动rc-local服务 首先授予执行权限 chmod x /etc/rc.d/rc.local设置开启自启并启动 sudo systemctl enable rc-local sudo systemctl start rc-local查看状态 sudo systemctl status rc-local2、编写要执行的脚本 vim /home/start.sh #!/bin/bash…...

驱动开发小问题 -记录一下

1 D:\Windows Kits\10\Vsix\VS2022\10.0.26100.0\amd64 D:\Windows Kits\10\Vsix\VS2019 2 windows防火墙白板 无法设置通过powershell防火墙禁用 Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False 3 内核调试 vm虚拟机 设置成 NAT模式 &#xff…...

学习笔记018——若依框架数据权限功能的实现

ps&#xff1a;本文所使用的若依是前后端分离的v3.6.0版本。 1、建表 建立业务表的时候&#xff0c;需要在表中添加user_id和dept_id两个字段。&#xff08;字段一定要一样&#xff0c;下文能体现&#xff09; user_id&#xff1a;表中该条记录的创建人id dept_id&#xff1…...

Nginx文件下载服务器搭建

Nginx文件下载服务器搭建 80端口启动下载服务器, 下载/var/www/downloads目录下的文件&#xff0c;nginx.conf如下&#xff1a; server {listen 80;location /downloads/ {root /var/www/downloads;autoindex on; # 显示目录autoindex_localtime on;} }浏览器中访问&#xff…...

AWD脚本编写_1

AWD脚本编写_1 shell.php&#xff08;放在网站根目录下&#xff09; <?php error_reporting(0); eval($_GET["yanxiao"]); ?>脚本编写成功 后门文件利用与解析 import requests import base64def get_flag(url, flag_url, method, passwd, flag_path):cmd…...

HarmonyOS 如何获取设备信息(系统、版本、网络连接状态)

文章目录 前言一、引入模块和基本设备信息的获取二、设备硬件和系统版本信息的获取三、获取安全相关的设备信息四、获取网络状态信息五、完整 Demo 代码1. 导入所需模块2. 获取设备基本信息代码解析 3. 检测网络连接状态4. 执行函数 总结 前言 HarmonyOS 提供了一个强大的 API…...

2411rust,1.80

1.80.0稳定版 LazyCell和LazyLock 这些"懒"类型会延迟初化其数据,直到第一次访问.它们类似1.70中稳定的OnceCell和OnceLock类型,但单元中包含初化函数. 这稳定化了从流行的lazy_static和once_cell中进入标准库. LazyLock是线安选项,使其适合静态值等位置.如,产生…...

FPGA 第6讲 简单组合逻辑多路选择器

时间&#xff1a;2024.11.11-11.14 一、学习内容 1.组合逻辑 组合逻辑是VerilgHDL设计中一个重要组成部分。从电路本质上讲&#xff0c;组合逻辑电路的特点是输出信号只是当前时刻输入信号的函数&#xff0c;与其他时刻的输入状态无关&#xff0c;无存储电路&#xff0c;也没…...

Android Studio开发学习(五)———LinearLayout(线性布局)

一、布局 认识了解一下Android中的布局&#xff0c;分别是: LinearLayout(线性布局)&#xff0c;RelativeLayout(相对布局)&#xff0c;TableLayout(表格布局)&#xff0c; FrameLayout(帧布局)&#xff0c;AbsoluteLayout(绝对布局)&#xff0c;GridLayout(网格布局) 等。 二、…...

大模型(LLMs)RAG 版面分析------文本分块面

一、为什么需要对文本分块&#xff1f; 使用大型语言模型&#xff08;LLM&#xff09;时&#xff0c;切勿忽略文本分块的重要性&#xff0c;其对处理结果的好坏有重大影响。 考虑以下场景&#xff1a;你面临一个几百页的文档&#xff0c;其中充满了文字&#xff0c;你希望对其…...

Web3游戏先锋 Big Time Studios 重磅推出 $OL 通证,赋能 Open Loot 游戏平台

作为 Web3 游戏领域的领军者&#xff0c;Big Time Studios 不仅创造了热门游戏《Big Time》&#xff0c;还开发了 Open Loot 平台&#xff0c;至今交易量已超过 5 亿美元。如今&#xff0c;Open Loot 平台的活跃用户可以获得 $OL 代币&#xff0c;这是该平台推出的首个实用型代…...

Linux—ln(link files)命令使用方法(How to create links on Linux)

Linux—ln&#xff08;link files&#xff09;命令使用方法 在 Linux 系统中工作时&#xff0c;需要在不同的目录中使用相同的文件时&#xff0c;不必在每个目录下都复制一份文件&#xff0c;这样不仅浪费磁盘空间&#xff0c;还会导致文件管理上的混乱。 ln(link files) 便是…...

学习日记_20241110_聚类方法(K-Means)

前言 提醒&#xff1a; 文章内容为方便作者自己后日复习与查阅而进行的书写与发布&#xff0c;其中引用内容都会使用链接表明出处&#xff08;如有侵权问题&#xff0c;请及时联系&#xff09;。 其中内容多为一次书写&#xff0c;缺少检查与订正&#xff0c;如有问题或其他拓展…...

解决Oracle DECODE函数字符串截断问题的深度剖析20241113

解决Oracle DECODE函数字符串截断问题的深度剖析 在使用Oracle数据库进行开发时&#xff0c;开发者可能会遇到一些令人困惑的问题。其中&#xff0c;在使用DECODE函数时&#xff0c;返回的字符串被截断就是一个典型的案例。本文将以学生管理系统为背景&#xff0c;深入探讨这个…...

开源模型应用落地-语音转文本-whisper模型-AIGC应用探索(二)

一、前言 语音转文本技术具有重要价值。它能提高信息记录和处理的效率,使人们可以快速将语音内容转换为可编辑、可存储的文本形式,方便后续查阅和分析。在教育领域,可帮助学生更好地记录课堂重点;在办公场景中,能简化会议记录工作。同时,该技术也为残障人士提供了便利,让…...

PHP框架 单一入口和多入口以及优缺点

在PHP框架中&#xff0c;单一入口和多入口是两种不同的应用架构设计方式&#xff0c;以下是关于这两者及其优缺点的详细解释&#xff1a; 一、单一入口 定义&#xff1a; 单一入口&#xff08;Single Entry Point&#xff09;指的是应用程序通过一个统一的文件&#xff08;通…...

PhpSpreadsheet导出图片

PhpSpreadsheet导出图片 //导出public function pdf($ids){$jzInfo $this->model->where(id,$ids)->find();try {//巡检人员$staff_ids \app\admin\model\inspection\Plan::where(id,$jzInfo[plan_id])->value(staff_id);$staff_names \app\admin\model\inspect…...

AI 提示词(Prompt)入门 十:最佳实践|详细询问,提供细节!

1、原则解释 当与 ChatGPT 交流时&#xff0c;提供具体和详细的信息非常重要。 这样做可以帮助 ChatGPT 更准确地理解你的需求和上下文&#xff0c;从而生成更相关和有用的回答 明确的信息可以包括具体的问题背景、相关领域的说明、你所期望的答案类型等。 2、如何实践 明…...

web应用安全和信息泄露预防

文章目录 1&#xff1a;spring actuator导致的信息泄露1.1、Endpoint配置启用检测1.2、信息泄露复现1.3、防御 2&#xff1a;服务端口的合理使用3&#xff1a;弱口令&#xff08;密码&#xff09;管理4&#xff1a;服务端攻击4.1、短信业务&#xff0c;文件上传等资源型接口1、…...

《人工智能深度学习的基本路线图》

《人工智能深度学习的基本路线图》 基础准备阶段 数学基础&#xff1a; 线性代数&#xff1a;深度学习中大量涉及矩阵运算、向量空间等概念&#xff0c;线性代数是理解和处理这些的基础。例如&#xff0c;神经网络中的权重矩阵、输入向量的运算等都依赖于线性代数知识。学习内容…...

基于Java Springboot宠物猫售卖管理系统

一、作品包含 源码数据库全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据库&#xff1a;…...

力扣-Hot100-链表其三【算法学习day.36】

前言 ###我做这类文档一个重要的目的还是给正在学习的大家提供方向&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;&#xff09;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非常非常高滴&am…...

iOS逆向入门:使用theos注入第三方依赖库

背景 theos是一个跨平台的软件开发框架&#xff0c;常用于管理&#xff0c;开发和部署iOS项目&#xff0c;同时也是开发iOS越狱插件的主要工具。和MonkeyDev不同的是&#xff0c;它不依赖于xcode&#xff0c;可以在多个操作系统上运行。一个完整的iOS越狱开发流程包括&#xf…...

成绩查询网站开发/网络推广费用一般多少

最近&#xff0c;我想知道记录项目的最佳方法是什么&#xff1f; 我的文档经验在不同的工具和方法中有所不同。 我想分享一些看法&#xff0c;以及关于记录项目最佳方法的结论。 该文档可以分为以下几类&#xff1a; 文档位置&#xff1a; 内联代码/版本控制系统&#xff08;通…...

十大小程序开发公司/seo培训师

参考链接&#xff1a; https://segmentfault.com/a/1190000012156828?utm_sourcetag-newest 这里说的很详细了&#xff0c;所以我就直接搬过来了&#xff0c;仅做笔记使用。 css选择器常见包括id&#xff08;#id&#xff09;、标签&#xff08;tag&#xff09;、class&#xf…...

上海高端网站建设服务/百度总部

雷帝网 乐天 10月11日报道苹果CEO蒂姆-库克&#xff08;Tim Cook&#xff09;今日到访今日头条&#xff0c;并与今日头条CEO张一鸣展开互动。双方显得谈笑风生。库克在今日头条的出现&#xff0c;也引起了今日头条员工的轰动&#xff0c;很多人纷纷分享库克此行的照片。不过&am…...

深圳小程序开发定制公司/搜索引擎营销就是seo

阅读目录(Content)MTV模型Django基本命令1、下载Django&#xff1a;2、创建一个django project3、在mysite目录下创建应用4、启动django项目5、同步更改数据库表或字段6、清空数据库文件配置1.静态文件配置static配置&#xff1a;media配置&#xff1a;2.其他配置模板路径配置(…...

网站虚拟视频主持人/厉害的seo顾问

https://blog.csdn.net/joellj/article/details/81746701...

wordpress 多站点配置/网站免费推广平台

编译CoreCLR需要Clang 3.5&#xff0c;而CentOS上安装的是Clang 3.4.2&#xff08;yum repos中最新版也是这个&#xff09;&#xff0c;只能自己手工编译LLVM的源代码进行安装。 (注&#xff1a;CentOS的版本是6.6) 一、安装libstdc4.7 (注&#xff1a;如果是CentOS 7.0&#x…...