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

【Linux进程控制详解】

一、创建进程

使用pid_t fork() 创建一个子进程
进程调用fork,当控制转移到内核fork代码后,内核会做:

  • 分配新的内存块和内核数据给子进程
  • 将父进程的部分数据结构拷贝给子进程
  • 添加子进程到系统列表当中
  • fork返回,开始调度器调度

在这里插入图片描述
当一个进程调用fork后,就会有两个二进代码相同的进程,它们都运行在同一个地方,但是它们开启不一样的旅程。
在这里插入图片描述
所以我们知道fork之前父进程独立执行,fork之后父子进程分流执行。
我们都知道数据段在页表当中的权限是可读的,但是一旦创建了子进程,操作系统会把权限改为只读的。当子进程尝试写入的时候,操作系统就会报错。
在这里插入图片描述
操作系统会对当前情况进行判断分类:

判断是不是野指针,如果是就终止进程,不是就会发生写时拷贝,更改回权限

为什么创建子进程后,不直接把数据分开呢?还要写时拷贝?

直接拷贝将父子进程的数据分开是可以的,但是假设子进程对数据是只读的呢?这种情况就没必要进行拷贝了,父进程的代码和数据很小,每次创建子进程都要进行拷贝,这样以来就会产生时间浪费,以及内存的浪费。子进程读取父进程的数据,直接用父进程的就可以了,子进程要进行写入的时候,再给子进程申请。写时拷贝的本质就是一种惰性申请,这样可以提高内存使用率。

为什么要拷贝,能不能直接开辟对应的空间就好了?

不需要,开辟虚拟地址空间就可以了,真正需要用到的时候,操作系统才会做内存级的申请,构建完整的映射关系,本质上是一种惰性的申请。

二、进程终止

进程终止本质上就是释放系统资源,释放进程申请的相关内核数据结构和对应的数据代码

进程退出的场景:

  • 代码运行完毕结果正确
  • 代码运行完毕结果错误
  • 代码异常终止

问题:进程终止的时候操作系统要做什么?

进程终止时,操作系统要释放进程资源,停止CPU对进程的调度,更新进程状态

问题:我们在写代码的时候总是要写return 0(或是return别的数)那这个return返回这个是什么意思呢?给了谁?

return 0我们叫进程退出的退出码,它会被系统获得,让系统辨别该进程的执行情况

为什么要有退出码呢?

我们创建进程来完成任务的时候,进程完成得怎么样我们是要知道结果的吧,那我们要怎么样才能得到结果呢?
进程返回0表示程序运行成功
!0表示失败,例如1、2、3等等

char* strerror(int errnum) //将错误码转化为可读错误信息字符串

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
由上面程序运行的结果我们可以看到,一共有134个错误,其他都是未知的。
将来这个退出码会被写到PCB中,父进程通过子进程的pid就可以找到子进程,获取子进程的信息,这也就是为什么子进程在退出时,状态会被设置为僵尸状态,不能立即释放所有资源,要保留PCB的原因了。

进程退出的方法

方法一main()函数进行return n,n 表示该进程的退出码
在这里插入图片描述
方法二调用exit(n),n表示进程的退出码
在这里插入图片描述
方法三直接调用系统调用_exit(n)
在这里插入图片描述

return和exit的对比

我们都知道return一般是函数调用结束的时候,表示进程退出
exit()则表示进程结束,在代码中任何地方调用都会导致进程退出
具体看以下代码:
在这里插入图片描述
在这里插入图片描述

exit和_exit对比

看下面的代码
在这里插入图片描述
运行我们会发现,它前五秒光标一直没有打印出内容,其实它是被写入到缓冲区内,main函数中return表明进程结束,输出缓冲区,在进程结束的时候会自动刷新。同理exit终止进程也会主动刷新缓冲区。而_exit却跟以上两种不同,看以下代码:
在这里插入图片描述
_exit会直接终止进程,不会刷新缓冲区

我们都知道库和系统是上下层的关系,系统调用的存在就是为了保证用户安全的访问操作系统,也就是说只有系统调用才可以和操作系统交互。
进程退出的时候需要释放资源,这些工作都是由操作系统完成的,我们调用C语言的库函数exit为什么可以让进程退出呢?答案是进程终止绝对要调用系统调用,必须让操作系统完成真正的进程删除退出,所以库函数的底层一定封装了系统调用。

http://www.dtcms.com/a/344037.html

相关文章:

  • Windows应急响应一般思路(二)
  • 3 种无误的方式删除 Itel 手机上的短信
  • 车载 GPS 与手机导航的终极对决:谁在复杂路况下更胜一筹?
  • 开源文件加密工具【PicoCrypt】
  • [net]基于asp.net的校园网站的设计与实现/基于c#的校园论坛系统的设计与实现
  • 微软获评2025年Gartner®容器管理魔力象限™领导者
  • 深度学习在股票量化中的应用
  • AP服务发现PRS_SOMEIPSD_00160的解析
  • 项目中优惠券计算逻辑全解析(处理高并发)
  • 河南萌新联赛2025第(六)场:郑州大学(补题)
  • Unity UnityWebRequest高级操作
  • Masked Language Model 如何重塑大模型的预训练
  • 如何轻松永久删除 Android 手机上的短信
  • 如何从根源上理解并解决前端的CORS跨域问题
  • apt update Ign and 404 Not Found
  • docker cuda版安装 dockercuda版安装
  • 哪款云手机比较好用呢?
  • 链式法则解释上游梯度应用
  • 《Windows Server 2022》 [2025年8月版 ] [官方IOS] 下载
  • 设计模式:抽象工厂模式
  • DeepSeek辅助编写的测试xlsx文件写入性能的程序
  • 多线程下为什么用ConcurrentHashMap而不是HashMap
  • Python万里长征6(非教程)pandas筛选数据三基础、三核心、三高级
  • Kafka 为什么具有高吞吐量的特性?
  • C# 浮点数与定点数详细解析
  • 邀请函 | 2025达索系统高峰论坛,跨界融合定义未来制造
  • SamOutVXP:革命性轻量级语言模型,突破传统推理限制
  • 不同类型代理 IP 在爬虫场景下的表现对比
  • 苹果紧急修复ImageIO零日漏洞CVE-2025-43300,已被在野利用
  • 开源AI编程工具Kilo Code的深度分析:与Cline和Roo Code的全面对比