进程控制(上)【Linux操作系统】

进程控制

写时拷贝

本质是一种减少深拷贝的方法
Linux中有很多拷贝的场景都用得上写时拷贝,下面以创建子进程时的写时拷贝为例:

子进程被创建的时候:
会继承父进程的mm_struct和页表
所以子进程刚刚继承时,父子进程的代码和数据都是共享的

系统是如何知道子进程/父进程修改数据的时候要发生写时拷贝的呢?
①父进程在使用fork创建子进程之前,就会把页表中的数据区的权限改成r(只读)
这样子进程继承到的页表中的数据区就也是只读的

②当子进程/父进程尝试修改数据区中的数据时,就是修改只读数据项,页表就会报错,就会触发缺页中断

③系统发现缺页中断之后,就会检测
1,如果发现用户要修改的这个区域一定是只读的,就把进程杀掉
2,如果这个区域一定是读写的,只是页表中的权限设置成只读的了,此时系统就会进行写时拷贝
在这里插入图片描述

所以:不止创建子进程写时拷贝的时候是这种原理
只要可能发生写时拷贝的数据被页表管理着,就都可以通过这个原理实现写时拷贝



错误码

用来判断进程任务执行是否成功,如果失败了错误是什么

main函数的返回值其实是错误码,是返回给父进程/操作系统的
在这里插入图片描述
进程错误码的的取值范围是[0-255],即一个字节
因为使用wait/waitpid等待回收错误码的时候,只给它留了8个比特位



进程中止

进程中止的方法:

①在main函数中return

②在任何地方使用exit函数[exit函数的参数就是错误码,它的头文件是stdio.h]

③_exit使用方法和exit一模一样


exit与_exit的区别:

本质区别就是exit是用户层的库函数,_exit是内核层的系统调用
所以exit函数中,调用_exit中止进程之前,可以进行一些用户层的收尾工作
比如:
exit中止进程时,会刷新用户级缓冲区和内核级缓冲区
也就是如果输出缓冲区中有数据,使用exit中止它会帮我们打印出来

_exit中止进程时,不会刷新用户级缓冲区,只会刷新内核级缓冲区

②exit是库里面的函数,是操作系统之外的操作,使用操作系统的资源时,只能对操作系统调用接口进行封装
exit其实就封装了_exit

_exit是系统调用接口,是操作系统内部的操作
在这里插入图片描述

所以:
其实我们之前再使用c/c++等高级语言时,所说的缓冲区都是语言级(用户级)的缓冲区

这个缓冲区里面的内容是存储在c/c++的标准库中的,即存储在共享区的

不是存储在操作系统中的内核级缓冲区
不然_exit中止进程时,就也能把缓冲区中信息输出/输入
但是因为语言级缓冲区在操作系统的上层,所以_exit中止进程后,内核缓冲区就关闭了,语言缓冲区中的数据没办法进入操作系统了
操作系统没看见语言缓冲区中传来信息,就以为里面没有



进程等待

wait(不常用)

头文件:sys/types.hsys/wait.h
返回值:pid_t[小于0说明回收失败,大于0时回收成功,返回的是回收的子进程的pid]
参数:

作用:等待并回收任意一个子进程
在这里插入图片描述


waitpid[常用]

头文件:sys/types.hsys/wait.h
返回值:pid_t n
①n小于0,说明回收失败/函数调用失败
②n大于0,回收成功,返回的是成功回收的子进程的pid
③n等于0(只有非阻塞等待才会出现),则表示函数调用成功,但是子进程还没执行完,还没退出

参数1.pid_t pid

如果是子进程的pid,就表示指定等待这个子进程
如果是-1,就表示等待任意一个进程


参数2,int* status

如果传nullptr则表示不需要获取退出信息==

即:用户自己定义一个int类型的变量
再把它的地址传进waitpid里面,操作系统就会把进程的PCB中存储的退出信息给status

status其实并不是一个整数,而是一个类似位图的东西
因为进程结束,分两种情况:
①正常退出,也就是通过main函数的return或者exit退出,这样就可以返回退出码
所以只有正常退出才能返回退出码(错误码)

②异常退出,也就是进程运行的途中,空指针访问/野指针等直接导致进程崩溃了
这样进程根本就运行不到返回退出码的地方
但是异常退出,也会有自己的退出信号码
[通过kill -l命令,可以看到Linux中所有的退出信号以及其对应的退出信号码]

进程之所以会异常退出,是因为进程运行时出现了较严重的错误(野指针,除0等
操作系统识别到以后,在代码还没跑完的时候,就直接使用信号中止了进程


所以
status中不仅仅存储了退出码,还存储了其他的退出信息

具体的:
status的:
①最低的7个比特位存储退出信号值
②第8个比特位存储core dump标志
③第9~16个比特位存储退出码
在这里插入图片描述

宏:
WIFEXITED(status):
若为正常终止子进程返回的状态,则为真(查看进程是否是正常退出)

WEXITSTATUS(status):
若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)


参数3.标识是阻塞等待,还是非阻塞等待

如果该参数是0,表示阻塞式等待
如果为WNOHANG,表示非阻塞式等待



使用子进程完成任务的好处

①非阻塞等待或者创建多个子进程时,父子进程可以同时运行,父进程不用等子进程,提高并发度

②进程具有独立性,所以如果子进程出了问题,不影响父进程

③数据快照,子进程被fork出来,继承了父进程的PCB,页表等东西之后
就获取到了fork时父进程的数据
也就是对子进程从父进程那里获取到的数据进行了快照
快照之后,其他任何进程对这一块数据进行修改,这个子进程都“看不见”
因为写时拷贝,或者说进程具有独立性。所以数据快照之后,其他进程可以对这个数据任意修改

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

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

相关文章

Flutter 强制横屏

在 Flutter 中,可以通过设置 SystemChrome 来强制应用横屏显示。以下是实现这一功能的详细步骤和代码示例: 步骤 1:导入必要的包 确保在文件顶部导入了 services.dart 包,因为 SystemChrome 类位于该包中。 import package:flut…

Git完全指南:从入门到精通版本控制 ------- Git核心命令(6)

Git核心命令完全指南:从入门到高效协作 前言 在软件开发领域,Git已成为现代版本控制的代名词。据统计,全球超过90%的开发团队使用Git进行代码管理。然而,许多开发者仅停留在基础命令的机械使用层面,未能真正掌握Git命…

关于Newtonsoft.Json

历史 Newtonsoft.Json(也称为 Json.NET)是由 James Newton - King 开发的一个开源的 JSON 处理库,它于 2007 年首次发布。在早期,.NET 平台缺乏一个强大且灵活的 JSON 处理工具,Newtonsoft.Json 应运而生,…

git reset详解

一、git reset 的核心作用 用于 移动当前分支的 HEAD 指针 到指定的提交,并可选择是否修改工作区和暂存区。 ⚠️ 注意:若提交已被推送到远程仓库,强制重置(--hard)后需谨慎操作,避免影响协作。 二、三种模…

【unity游戏开发入门到精通——UGUI】CanvasScaler画布缩放器组件

注意:考虑到UGUI的内容比较多,我将UGUI的内容分开,并全部整合放在【unity游戏开发——UGUI】专栏里,感兴趣的小伙伴可以前往逐一查看学习。 文章目录 一、CanvasScaler画布缩放器组件是什么二、CanvasScaler的三种适配模式1、Cons…

Kubernetes控制平面组件:API Server Webhook 授权机制 详解

云原生学习路线导航页(持续更新中) kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计(一)Kubernetes架构原则和对象设计(二)Kubernetes架构原则和对象设计(三)Kubernetes控…

Python自动化办公

第五篇:Python自动化办公:10行代码搞定重复性工作 适合读者:职场人士、数据分析师 | 阅读时长:12分钟 引言 每天重复处理Excel、PDF或邮件?Python可以帮你自动化这些枯燥任务,节省90%的时间。本文通过实际…

【3】k8s集群管理系列--包应用管理器helm之chart资源打包并推送到harbor镜像仓库

一、chart资源打包 helm package ./web-chart # 当前目录会生成一个tgz的压缩文件二、安装help push插件(用于推送前面打包的文件,到镜像仓库) .1 下载help-push二进制文件 wget https://github.com/chartmuseum/helm-push/releases/down…

【SpringBoot Druid Mysql多数据源整合】

SpringBoot Druid Mysql多数据源整合 一、背景二、配置结果2.1 SpringBoot java 类配置2.1.1 启动类配置2.1.2 java Config配置 2.2 SpringBoot yml 配置 三、mybatis插件配置3.1 PageHelper的yml配置3.2 mybatis设置自定义字段默认值 四、配置解释 一、背景 公司项目需要连接另…

GGML源码逐行调试(中)

目录 前言1. 简述2. 加载模型超参数3. 加载词汇表4. 初始化计算上下文5. 初始化计算后端6. 创建模型张量7. 分配缓冲区8. 加载模型权重结语下载链接参考 前言 学习 UP 主 比飞鸟贵重的多_HKL 的 GGML源码逐行调试 视频,记录下个人学习笔记,仅供自己参考&…

kubectl的使用

查看集群有多少节点 kubectl get nodes 获取集群状态的摘要信息(组件信息) kubectl get cs 查看所有命名空间下的所有pod的状态和信息 kubectl get pods --all-namespaces 查看所有命名空间的状态和信息 kubectl get namespaces /ns 查看kube-system…

git在分支上会退到某个指定的commit

1、在idea上先备份好分支(基于现有分支new branch) 2、在gitlab管理端删除现有分支 3、在idea中大卡terminal,执行 git log 查看commit log ,找到要会退到的commit唯一码,然后执行git reset 唯一码 4、查看本地代码状态 git st…

动态路由, RIP路由协议,RIPv1,RIPv2

动态路由 1、回顾 路由:从源主机到目标主机的过程 源主机发送数据给目标主机,源主机会查看自身的路由信息 如果目标主机是自己同网段,源主机查看的是直连路由 如果目标主机和自己不同网段,源主机查看的是静态路由、动态路由、默…

前端面试-工程化(webpack、vite)

Webpack 相关问题(25道) Webpack 的核心概念有哪些?(Entry、Output、Loader、Plugin、Module、Bundle)如何配置 Webpack 的多入口和多出口?Webpack 的 Tree Shaking 实现原理是什么?Loader 和 …

idea 2024 build菜单不见了

Q如题 idea 2024 新版UI添加build和recompile菜单 A如图,右键顶部栏之后,点击Add to Main Toolbar菜单,在里面就能找到Build菜单,添加接口。 Recompile菜单的话在Customize Toolbar中搜索添加才行。

【开源项目】Excel手撕AI算法深入理解(三):时序(RNN、mamba)

项目源码地址:https://github.com/ImagineAILab/ai-by-hand-excel.git 一、RNN 1. RNN 的核心思想 RNN 的设计初衷是处理序列数据(如时间序列、文本、语音),其核心特点是: 隐藏状态(Hidden State&#xff…

pycharm已有python3.7,如何新增Run Configurations中的Python interpreter为python 3.9

在 PyCharm 中,如果你已经安装了 Python 3.9,并且希望在 Run Configurations 中新增一个 Python 3.9 的解释器,可以按照以下步骤操作: 步骤 1:打开 PyCharm 设置 点击 PyCharm 左上角的 File 菜单。选择 Settings&am…

【H桥电机驱动电路原理】-学习笔记

工作原理 电路分析 这是一个由晶体管构成的 H 桥电机驱动电路 ,以下是对其各部分的介绍: 核心器件 晶体管:电路中使用了 PNP 型的 SS8550(Q5、Q6 )和 NPN 型的 SS8050(Q9、Q10、Q13、Q14 )。…

【家政平台开发(49)】解锁家政平台上线密码:服务器选型与配置全攻略

本【家政平台开发】专栏聚焦家政平台从 0 到 1 的全流程打造。从前期需求分析,剖析家政行业现状、挖掘用户需求与梳理功能要点,到系统设计阶段的架构选型、数据库构建,再到开发阶段各模块逐一实现。涵盖移动与 PC 端设计、接口开发及性能优化,测试阶段多维度保障平台质量,…

驱动开发硬核特训 · Day 10 (理论上篇):设备模型 ≈ 运行时的适配器机制

🔍 B站相应的视屏教程: 📌 内核:博文视频 - 总线驱动模型实战全解析 敬请关注,记得标为原始粉丝。 在 Linux 驱动开发中,设备模型(Device Model)是理解驱动架构的核心。而从软件工程…