Linux中进程的控制
一、进程的创建
1、知识储备
进程的创建要调用系统接口,头文件 #include<unistd.h> 函数fork()
由于之前的铺垫我们现在可以更新一个概念
进程 = 内核数据结构(task_struct, mm_struct, 页表....)+ 代码 + 数据
所以如何理解进程的独立性呢?
就是上述组成进程的结构都是独立的,互不影响的。
那为什么 fork() 返回的是子进程的pid呢?
是为了让父进程对子进程进行表示和管理。
2、理解fork()
(1)fork() 常见用法
a、在一个代码中通过 fork() 不同的返回值用 if else分流,以达到不同进程执行不同代码的目的。
b、可以让父子进程独立进行完全不同的代码。
(2)fork() 失败的原因
a、操作系统中进程太多。
b、实际用户创建的进程太多,超出规定个数。
二、进程的终止
首先我们要知道进程是先创建内核数据结构,再加载代码和数据。
1、终止的表现
会释放代码和数据所占据的空间,释放内核数据结构(task_struct 会延期释放)
2、终止的三种情况
(1)观察现象
首先我们先观察一个现象
当我们以前在写c语言代码时,我们都是 return 0; 结尾,当我们今天 return 100; 时,用 echo $? 命令获取进程的退出码时,就会发现退出码和 return 后面的数字是一样的。
(2)解释 echo $?
echo:内建命令,打印bash内部变量数据。
$:访问变量内容。
?:父进程bash获取最近一个子进程的退出码。
(3)退出码
退出码0是成功,非0是失败。
每一个非0数都有不同的失败原因。
头文件 #include<string.h> 函数 char* strerror(int num) 可以查看退出码。
上图只截了一部分退出码。
退出码的作用就是告诉父进程,子进程把任务完成的怎么样。
结论:当代码跑完时,结果的正确与否是由退出码反馈给用户的。
(4)退出信号
与退出码不同,退出信号是代码还没跑完,系统就崩溃了(操作系统发现进程做了不该做的事,比如访问野指针等等),操作系统就会杀死进程。
所以一旦出现异常,退出码也就没有意义了,但是返回的退出信号是有意义的。
例如:Segmentation fault 就是段错误,代码段是有错误的。
退出信号的本质:操作系统给进程发信号并终止进程。
之前我们说kill -9 可以直接杀死进程也就是这个原因,而我们上面提到的段错误 Segmentation fault 就是操作系统发送了 kill -11 信号。
(5)总结
衡量一个进程的退出,只要看退出码和退出信号。
先确认是否异常,若不是才看退出码。
所以在子进程的 task_struct 中就会有 exit_code(退出码) exit_signal(退出信号),在执行完代码后写入退出码和退出信号供父进程读取。
3、如何终止
(1)main()函数中的 return 代表进程终止(普通函数 return 表示函数结束)
(2)调用头文件#include<stdlib.h> 函数 void exit(int status) status相当于退出码,exit等价于return
(3)调用头文件#include<unistd.h> 函数 void _exit(int status),基本与exit函数相同,一个是c库函数,一个是系统调用。
区别
exit 执行时会冲刷缓冲区,但是 _exit不会,所以其实这里所说的缓冲区只是c库层面的,不是系统调用层面的缓冲区。
exit本质就是底层调用 _exit
三、进程等待
任何子进程在退出的情况下必须要被父进程等待。如果父进程不管,子进程就会处于僵尸状态,导致内存泄漏。
三、进程的等待
1、为什么父进程要等待子进程
(1)解决僵尸问题,回收系统资源。(必须)
(2)获取子进程退出信息,知道子进程为什么退出。(可选)
2、怎么等待
(1)wait 函数
头文件 #include<sys/types.h> #include<sys/wait.h>
函数 pid_t wait(int* status)
等待成功返回子进程的pid,wait(NULL)表示父进程等待任意一个子进程退出。
若子进程一直不退出,父进程就进入阻塞等待。
阻塞等待的本质:把父进程设为非运行状态(S),链入到子进程队列中,子进程退出,父进程唤醒。
(2)waitpid 函数
头文件 #include<sys/types.h> #include<sys/wait.h>
函数 pid_t waitpid(pid_t id, int* status, int options)
waitpid(-1, NULL, 0)等价于wait(NULL)
a、理解参数 id
id 表示要等待哪个子进程
所以理解代码:
pid_t id = fork();
waitpid(id, NULL, 0);
在父进程中fork()返回子进程pid,所以就指定了要返回哪个子进程了。
b、理解参数 status
status是输出型参数(例如 scanf(),就是把数值写入到一个变量中),输出的是退出信息(包括退出码和退出信号)
理解额代码:
我们知道int有32位bit位,status只考虑低16位
获取退出码:(status>>8) & 0xFF
获取退出信息:status & 0x7F
c、获取退出码的宏
WIFEXITED(status) 代码正常走完就返回真
WEXITSTATUS(status) 若WIFEXITED为真就提取退出码
(3)非阻塞等待
上述父进程都是等子进程跑完之后才工作的,这种都是阻塞等待,调用waitpid默认也是阻塞等待,但是我们想让父进程在等待时做其他事情,就要让 waitpid 中 option 设成 WNOHANG
此时返回值 < 0:等待失败。
返回值 = 0:检测成功,但是子进程未退出,等待下一次检测。
返回值 > 0:等待成功,并且父进程回收成功。
非阻塞等待 + 循环 = 非阻塞轮询
达到父进程能做其他事情。
相关文章:

Linux中进程的控制
一、进程的创建 1、知识储备 进程的创建要调用系统接口,头文件 #include<unistd.h> 函数fork() 由于之前的铺垫我们现在可以更新一个概念 进程 内核数据结构(task_struct, mm_struct, 页表....) 代码 数据 所以如何理解进程的独…...

【源码】Sharding-JDBC源码分析之JDBC
Sharding-JDBC系列 1、Sharding-JDBC分库分表的基本使用 2、Sharding-JDBC分库分表之SpringBoot分片策略 3、Sharding-JDBC分库分表之SpringBoot主从配置 4、SpringBoot集成Sharding-JDBC-5.3.0分库分表 5、SpringBoot集成Sharding-JDBC-5.3.0实现按月动态建表分表 6、【…...

Java | Leetcode Java题解之第273题整数转换英文表示
题目: 题解: class Solution {String[] singles {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"};String[] t…...

数据结构之深入理解简单选择排序:原理、实现与示例(C,C++)
文章目录 一、简单选择排序原理二、C/C代码实现总结: 在计算机科学中,排序算法是一种非常基础且重要的算法。简单选择排序(Selection Sort)作为其中的一种,因其实现简单、易于理解而受到许多初学者的喜爱。本文将详细介…...

使用vscode搜索打开的文件夹下的文件
右键空白处打开命令面板 摁一次删除键,删除掉图中的大于号 这样就能够找到例化的模块,文件具体在哪个位置,然后打开了...
力扣778.水位上升的泳池中游泳
力扣778.水位上升的泳池中游泳 二分 bfs class Solution {int dx[4] {1,0,-1,0},dy[4] {0,1,0,-1};public:int swimInWater(vector<vector<int>>& grid) {int n grid.size();auto check [&](int mid) -> bool{queue<pair<int,int>>…...

Nacos-2.4.0最新版本docker镜像,本人亲自制作,部署十分方便,兼容postgresql最新版本17和16,奉献给大家了
基于Postgresql数据库存储的nacos最新版本2.4.0,采用docker镜像安装方式 因业务需要,为了让nacos支持postgresql,特意花了两天时间修改了源码,然后制作了docker镜像,如果你也在找支持postgresql的nacos最新版本,恭喜你,你来的正好~ nacos-2.4.0 postgresql的数据库脚本…...

Halcon机器视觉15种缺陷检测案例_9找出所有网格顶点的位置
Halcon机器视觉15种缺陷检测案例_9找出所有网格顶点的位置 效果 原图 代码 *9找出所有网格顶点的位置 dev_update_off ()read_image (Image, 9找出所有风格顶点的位置) get_image_size (Image, Width, Height) *关闭已打开的窗口 dev_close_window ()dev_open_window (0, 0, …...

w30-python02-pytest入门
代码如下: import pytest class Test_Obj:"""测试类"""#用例级别前后置def setup(self):print(用例级别------的前置处理)def teardown(self):print("用例级别--------的后置处理")# 用例def test_case1(self):print(&quo…...

WPF+Mvvm项目入门完整教程-仓储管理系统(二)
目录 一、搭建一个主界面框架二、实现步骤1.主界面区域划分2.主界面区域实现 一、搭建一个主界面框架 主要实现主界面的框架样式和基础功能。这里特别说明一下,由于MvvmLight 已经过时不在维护,本项目决定将MvvmLight框架变更为 CommunityToolkit.Mvvm …...

SkyWalking入门搭建【apache-skywalking-apm-10.0.0】
Java学习文档 视频讲解 文章目录 一、准备二、服务启动2-1、Nacos启动2-2、SkyWalking服务端启动2-3、SkyWalking控制台启动2-4、自定义服务接入 SkyWalking 三、常用监控3-1、服务请求通过率3-2、服务请求拓扑图3-3、链路 四、日志配置五、性能剖析六、数据持久化6-1、MySQL持…...
exo项目目录架构
目录 .yml 文件是 YAML(YAML Aint Markup Language) exo项目目录架构 文件作用 topology、viz:项目拓扑结构可视化相关的代码或工具。 项目目录架构 文件作用 .yml 文件是 YAML(YAML Aint Markup Language) 文件的扩展名,YAML 是一种人类可读的数据序列化标准,通…...
mysql中where与on区别
WHERE子句 作用范围:WHERE子句主要用于过滤FROM子句返回的结果集。它可以在SELECT、UPDATE、DELETE语句中使用,以限制哪些行被包含在最终的查询结果中,或者哪些行被更新或删除。应用场景:当需要基于某些条件过滤结果集时…...
filebeat把日志文件上传到Es中配置(ES7版本)
默认的filebeat配置会把所有的索引都放到一个文件中,通过摸索发现可以自定义索引的名字、模板、生命周期 (重点注意)该配置文件只适应于ES版本是7,不适应于8的版本,两个版本的配置文件差异很大 /app/logs/info.log日…...

Vue Router基础
Router 的作用是在单页应用(SPA)中将浏览器的URL和用户看到的内容绑定起来。当用户在浏览不同页面时,URL会随之更新,但页面不需要从服务器重新加载。 1 Router 基础 RouterView RouterView 用于渲染当前URL路径对应的路由组件。…...

Apache压测工具ab(Apache Bench)工具的下载安装和使用示例
场景 Jmeter进行http接口压力测试: Jmeter进行http接口压力测试_接口压测两万量-CSDN博客 上面讲压测工具Jmeter的使用,下面介绍另外一个ab(Apache Bench)压测工具的使用。 apache bench apache bench是apache自带的压力测试工具。 ab不仅可以对ap…...
IPIDEA与Python爬虫:联手解锁全球电商数据宝库
IPIDEA与Python爬虫:联手解锁全球电商数据宝库 如何运用代理IP在电商领域进行高效数据采集。特别是在遭遇访问限制的情况下,如何优雅地绕过那些恼人的访问管理机制。当然,在我们的探险之旅中,开源神器PlugLink也将适时出场&#…...

Fine-BI学习笔记
官方学习文档:快速入门指南- FineBI帮助文档 FineBI帮助文档 (fanruan.com) 1.零基础入门 1.1 功能简介 完成四个流程:新建分析主题、添加数据、分析数据、分享协作。 示例数据获取:5分钟上手FineBI - FineBI帮助文档 (fanruan.com) 1.2 …...
AI 辅助编程 Coding AI 辅助研发组织的技术蓝图
简简单单 Online zuozuo:欢迎商业合作 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo :本心、输入输出、结果 简简单单 Online zuozuo :联系我们:VX :tja6288 / EMAIL: 347969164@qq.com 文章目录 AI 辅助编程 Coding A…...

VScode 批量操作
VScode 批量操作 批量修改 按住 alt/option 键, 选择需要批量操作的位置 如果是多行,则按住 altshift 键 可以直接操作 但是有时候比如变量命名,可能需要递增操作的命名 需要下载插件 Increment Selection 按照1的方法多选光标之后&am…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...

UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...