linux--fork()详解
fork()
参考链接:链接
进程控制原语包括:进程的建立、进程的撤销、进程的等待和进程的唤醒。
fork,在英语用译为叉子,形状像Y,反过来就如下图:

就是本来只有一个进行app,然后它调用了fork()函数,然后就产生了子进程,原来的进程叫父进程。这个子进程也是进程,但凡是进程,都有自己的虚拟地址空间。虚拟地址空间是从0到4G的大小,其中3-4G是属于内核的。创建完子进程后,父进程继续运行app(即原来的进程)的代码,刚创建出来的子进程拥有和父进程完全一样的代码段,数据段,也就是说完完全全拷贝了一份父进程,和父进程完全一样。即clone父进程0-3G的内容,而3-4G的kernel只需要重新映射一下到物理地址的kernel即可。但是操作系统要如何区分这两个进程呢?答案就是进程ID,即pid。pid是存储在PCB当中的类似身份证的东西。子进程会clone父进程的PCB到子进程,但是PCB里的pid会从操作系统中获取,得到新的pid。PCB存储在3-4G的内核中。 如下图:

fork()完以后,父进程和子进程由于有着同样的数据段和代码段,栈,PCB也大部分相同,所以两个进程就会干着同样的事情,这样对我们没有意义,所以需要识别哪个是父进程,哪个是子进程,然后让父进程接着干原来的事,子进程去干新的事情。
然后我们通过代码来观察:

这段代码在linux中运行,fork函数有两次返回,即调用一次,返回两次。在父进程返回子进程的pid,在子进程返回0,如果返回负数则表明fork失败。所以,我们根据返回值来判断当前进程是父进程还是子进程。
结果就是:

然后ps aux显示目前正在运行的进程:

pid为4296的是父进程,4297的是子进程。
解释:这段程序本身就是一个进程,然后它创建了一个子进程,它本身变为一个父进程。但是两个进程运行的都是同一段程序代码。当父进程运行时,fork返回大于0的数,那么我们就输出相应字符。而子进程运行时,fork返回0,那么我们再输出另外的字符。所以就有了上面的现象。
然后修改一下程序:

也就是让父进程休眠1s,一直打印,子进程休眠3s,一直打印。
然后输出如下:

明显是父进程打印得比较快。很符合所学知识,
然后kill 掉子进程,即 kill pid,然后就可以发现子进程没有输出了,也可以确认pid大1的是子进程。
也就是说,我们只能通过fork的返回值来判断当前进程是父进程还是子进程。
其实,fork底层是调用了内核的函数来实现fork的功能的,即先create()先创建进程,此时进程内容为空,然后clone()复制父进程的内容到子进程中,此时子进程就诞生了,接着父进程就return返回了。而子进程诞生后,是直接运行return返回的,然后接着执行后面的程序,这里注意:子进程是不会执行前面父进程已经执行过的程序了得,因为PCB中记录了当前进程运行到哪里,而子进程又是完全拷贝过来的,所以PCB的程序计数器也是和父进程相同的,所以是从fork()后面的程序继续执行。此时就按照前面的规则进行判断返回。如下图所示:

然后接下来介绍两个进程相关的函数,getpid()和getppid()
getpid()返回的是当前进程的pid,getppid()返回的是当前进程的父进程的pid。那前面说的父进程的父进程是啥呢?是shell。因为我们是子啊shell中 ./ 运行程序才创建起刚才的父进程的,所以shell是该父进程的父进程。

然后大家注意,如果此时在fork()前有变量n,那么创建子进程后,父进程和子进程的n不是同一个n,但是虚拟地址是一样的,因为也是完全拷贝父进程的,而进程间的虚拟地址都是独立的,对应的实际物理地址肯定是不同的,当你在两个进程中改变这个变量时,也可以发现这两个是不一样的,对进程线程有一定了解的都应该很好了解。

fork()的时候,父进程的虚拟地址映射着物理内存的实际的物理地址,clone()的时候,并不是在物理地址中直接再复制一份和父进程一样的物理内存块,而是子进程的虚拟地址也直接映射到同一物理内存块中,这就是读时共享。那这样的话不是就共享变量了吗?不就和前面说的矛盾了吗? 关键:当你操作这个物理内存块时(比如修改变量的值),再复制该部分的实际物理内存到子进程中,并不是全部复制。这就是写时复制。所以,当你在后面的程序中操作遍历n时,就会另辟内存块给子进程,表示这两者的独立。这就是读时共享,写时复制。
优点:可以减少实际物理内存的开销,也减少了完全复制一份内存块时cpu等资源的开销。同时减少使用的时间。所以linux引入了copy on write的机制。

程序功能就是:父进程不断地创建子进程,子进程经过30s后就结束进程。然后就看这引起的后果:
进程不断创建,ps aux和输出都非常巨大,这样由于pcb和变量的不断产生,内存消耗会很大,然后关键是cpu还要分配时间片给每个进程中的线程(此进程为一进程对应1线程),然后系统就会变得很卡,以至于其它不相关的进程操作起来也非常卡顿,因为cpu要在海量的进程中切换到你比较费时。
相关文章:
linux--fork()详解
fork() 参考链接:链接 进程控制原语包括:进程的建立、进程的撤销、进程的等待和进程的唤醒。 fork,在英语用译为叉子,形状像Y,反过来就如下图: 就是本来只有一个进行app,然后它调用了fork()函数…...
go_并发编程(1)
go并发编程 一、 并发介绍1,进程和线程2,并发和并行3,协程和线程4,goroutine 二、 Goroutine1,使用goroutine1)启动单个goroutine2)启动多个goroutine 2,goroutine与线程3࿰…...
第一百一十五回 权限管理包permission_handler
文章目录 概念介绍使用方法示例代码经验分享 我们在上一章回中介绍了局部动态列表相关的内容,本章回中将介绍权限管理包 permission_hanadler.闲话休提,让我们一起Talk Flutter吧。 概念介绍 权限是使用某种功能的授权,比如使用手机上的相机…...
【机器学习】sklearn数据集的使用,数据集的获取和划分
「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」:对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 sklearn数据集 二、安装sklearn二、获取数据集三、…...
Mysql之 optimizer_trace 相关总结
Mysql之 optimizer_trace 相关总结 MySQL官网介绍:https://dev.mysql.com/doc/dev/mysql-server/latest/PAGE_OPT_TRACE.html 1. 简介 MySQL优化器可以生成Explain执行计划,通过执行计划查看sql是否使用了索引,使用了哪种索; 但…...
【Linux命令详解 | wget命令】 wget命令用于从网络下载文件,支持HTTP、HTTPS和FTP协议
文章标题 简介一,参数列表二,使用介绍1. 基本文件下载2. 递归下载整个网站3. 限制下载速率4. 防止SSL证书校验5. 断点续传6. 指定保存目录7. 自定义保存文件名8. 增量下载9. 使用HTTP代理10. 后台下载 总结 简介 在编程世界中,处理网络资源是…...
DockePod信号处理机制与僵尸进程优化
Docke&Pod信号处理与僵尸进程优化 容器与信号的关系 SIGTERM信号:程序结束(terminate)信号,这是用来终止进程的标准信号,也是 kill 、 killall 、 pkill 命令所发送的默认信号。与SIGKILL不同的是该信号可以被阻塞和处理。通常用来要求程…...
NetApp StorageGRID 对象存储,使您能够跨公有、私有云和混合多云环境管理非结构化数据
NetApp StorageGRID 对象存储,使您能够跨公有、私有云和混合多云环境管理非结构化数据 主要优势 智能:了解行业领先的数据生命周期管理软件。 • 借助 NetApp StorageGRID 基于对象的存储解决方案的数据管理功能、您可以从大型非结构化数据中获得高价值…...
使用Java服务器实现UDP消息的发送和接收(多线程)
目录 简介:1. 导入必要的库2. 创建服务器端代码3. 创建客户端代码4. 实现多线程处理5. 测试运行示例代码:函数说明服务器端代码说明:客户端代码说明: 总结: 简介: 在本篇博客中,我们将介绍如何…...
Linux--查看端口占用情况
查看端口占用情况 在Linux使用过程中,需要了解当前系统开放了哪些端口,并且要查看开放这些端口的具体进程和用户,可以通过netstat命令进行简单查询 netstat命令各个参数说明如下: -t : 指明显示TCP端口 -u : 指明显示UDP…...
微信小程序|自定义弹窗组件
目录 引言小程序的流行和重要性自定义弹出组件作为提升用户体验和界面交互的有效方式什么是自定义弹出组件自定义弹出组件的概念弹出层组件在小程序中的作用和优势为什么需要自定义弹出组件现有的标准弹窗组件的局限性自定义弹出组件在解决这些问题上的优势最佳实践和注意事...
【数据结构】实现顺序表
目录 一.介绍顺序表二.实现顺序表1.创建多文件2.顺序表的存储方式3.函数的声明4.初始化顺序表5.清理顺序表6.打印顺序表7.扩容8.尾插8.尾删9.头插10.头删11.查找12.修改13.在pos位置插入13.在pos位置删除 三.全部代码1.SeqList.h2.SeqList.c3.Test.c 一.介绍顺序表 顺序表是用…...
【嵌入式环境下linux内核及驱动学习笔记-(19)LCD驱动框架2-FrameBuffer】
目录 1、 Frmebuffer(帧缓冲)操作介绍1.1 显示设备的抽象1.2 内存映像1.3 输出画面数据1.4 用户态下操作屏显1.4.1 用文件I / O 操作屏显1.4.2 mmap() 函数1.4.3 ioctl()函数1.4.5 用命令操作屏1.4.6 测试程序 2、Framebuffer总体框架2.1 框架要点2.2 fbmem.c分析2.…...
自己动手写数据库系统:实现一个小型SQL解释器(中)
我们接上节内容继续完成SQL解释器的代码解析工作。下面我们实现对update语句的解析,其语法如下: UpdateCmd -> INSERT | DELETE | MODIFY | CREATE Create -> CreateTable | CreateView | CreateIndex Insert -> INSERT INTO ID LEFT_PARAS Fie…...
HTML 与 XHTML 二者有什么区别
HTML 与 XHTML 二者有什么区别,你觉得应该使用哪一个并说出理由。 HTML 与 XHTML 之间的差别,主要分为功能上的差别和书写习惯的差别两方面。 关于功能上的差别,主要是 XHTML 可兼容各大浏览器、手机以及 PDA,并且浏览器也能快速正…...
fiddler抓包问题记录,支持https、解决 tunnel to 443
fiddler下载安装步骤及基本配置 fiddler抓包教程,如何抓取HTTPS请求,详细教程 可能遇到的问题及解决方案 1. 不能正常访问页面(所有https都无法访问) 解决方案:查看下面配置是否正确 Rules-customization 找到 OnB…...
Kubesphere中DevOps流水线无法部署/部署失败
摘要 总算能让devops运行以后,流水线却卡在了deploy这一步。碰到了两个比较大的问题,一个是无法使用k8sp自带的kubeconfig认证去部署;一个是部署好了以后但是没有办法解析镜像名。 版本信息 k8s:v1.21.5 k8sp:v3.3.…...
使用Nginx解决跨域问题
前言: 项目是公司的老项目,只有部署在服务器上的时候,项目才可以正常运行(接口是通的);现在需求:在现有的项目代码上进行修改,请求接口是第三方给的。接口是正常的,通过A…...
在 OpenCV 中使用深度学习进行年龄检测-附源码
文末附完整源码和模型文件下载链接 在本教程中,我们将了解使用 OpenCV 创建年龄预测器和性别分类器项目的整个过程。 年龄检测 我们的目标是创建一个程序,使用图像来预测人的性别和年龄。但预测年龄可能并不像你想象的那么简单,为什么呢?您可能会认为年龄预测是一个回归问…...
【BASH】回顾与知识点梳理(三十一)
【BASH】回顾与知识点梳理 三十一 三十一. 进程的管理31.1 给进程发送讯号kill -signal PIDlinux系统后台常驻进程killall -signal 指令名称 31.2 关于进程的执行顺序Priority 与 Nice 值nice :新执行的指令即给予新的 nice 值renice :已存在进程的 nice…...
济南精神心理专科:如何识别躯体化障碍的早期信号
济南躯体化障碍疾病就医选择难题在济南,面对躯体化障碍疾病的朋友最关心的是隐私和靠谱。选择一家好的医院至关重要,尤其是看躯体化障碍一定要选专科专业医院。这类医院不仅在专业诊疗上更有优势,还能提供更好的隐私保护和服务体验。本文将基…...
OpenClaw家装设计:Qwen2.5-VL-7B根据户型图生成3D效果示意图
OpenClaw家装设计:Qwen2.5-VL-7B根据户型图生成3D效果示意图 1. 为什么选择OpenClaw做家装设计自动化 去年装修新房时,我花了大量时间在设计师和施工队之间来回沟通。每次修改设计方案都需要等待设计师重新出图,周期长、成本高。直到发现Op…...
NVIDIA Profile Inspector完全掌握:从问题诊断到性能优化的效率提升指南
NVIDIA Profile Inspector完全掌握:从问题诊断到性能优化的效率提升指南 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector 许多玩家和创作者拥有高性能NVIDIA显卡,却因配置不当无法…...
指挥OpenClaw抓取数据折腾了一夜,我终于想到了邪修玩法
这段时间玩小龙虾玩得真上头,突然想起之前一直想要统计公众号的数据。 这工作交给小龙虾妥妥能胜任啊!但是吧……实际上执行出来的结果却不是这样的。 因为小白本地使用的是OpenClawAtomgit的方案,Atomgit主打一个不费一分钱,免…...
Qwen3-14B日志分析教程:ELK栈收集推理请求、响应、错误全链路追踪
Qwen3-14B日志分析教程:ELK栈收集推理请求、响应、错误全链路追踪 1. 为什么需要日志分析 当你在私有化部署Qwen3-14B模型时,可能会遇到各种问题:为什么推理速度突然变慢了?为什么API返回了错误响应?哪些请求消耗了最…...
WeClaw_42_Agent工具注册全链路:从BaseTool到意图识别的标准化接入
WeClaw_42_Agent工具注册全链路:从BaseTool到意图识别的标准化接入作者: WeClaw 开发团队 日期: 2026-03-29 版本: v1.0 标签: Agent 工具、BaseTool、意图识别、渐进式暴露、延迟注入📖 摘要 本文系统讲解 WeClaw Agent 工具注册的完整链路。当需要将一…...
第一次降AIGC率不知道从哪入手?这份保姆级操作手册帮你
第一次操作的话,照着下面的步骤来,15分钟内搞定降AIGC率、降AI工具保姆级测评2026、降AI。 工具选嘎嘎降AI(www.aigcleaner.com),达标率99.26%,有退款保障,操作也不复杂。 准备工作 需要准备的…...
火山引擎语音合成SDK实战:从快速调用到高级参数调优
1. 火山引擎语音合成SDK初体验 第一次接触火山引擎的语音合成SDK时,我正为一个智能客服项目发愁。客户要求系统能够用不同音色、不同情感的语音播报订单状态,而市面上大多数TTS服务要么太贵,要么效果生硬。直到同事推荐了火山引擎的解决方案&…...
PyTorch导入报错?手把手教你解决WinError 126找不到fbgemm.dll的问题(附libomp140.dll下载)
PyTorch导入报错终极解决方案:WinError 126缺失fbgemm.dll的深度修复指南 当你满怀期待地准备开始PyTorch深度学习项目时,突然遭遇"OSError: [WinError 126] 找不到指定的模块"错误,这感觉就像赛车手在起跑线上发现引擎无法启动。这…...
深入解析RS485接口:从硬件设计到工业应用
1. RS485接口基础解析 第一次接触RS485时,我也被它复杂的电气特性搞得一头雾水。直到在工厂里亲眼看到它如何稳定地穿过嘈杂的电机区域传输数据,才真正理解这个老牌工业接口的魅力。RS485本质上是一种差分信号传输标准,采用双绞线进行平衡传…...
