Linux进程——进程的创建(fork的原理)
前言:在上一篇文章中,我们已经会使用getpid/getppid函数来查看pid和ppid,本篇文章会介绍第二种查看进程的方法,以及如何创建子进程!

本篇主要内容:
- 查看进程的第二种方法
- 创建子进程
- 系统调用函数fork

在开始前,我先来回顾一下如何获取pid,ppid

进程要想区分就一定会有唯一的标示符,而pid,ppid初始化后就变为内核中的数据,也就是操作系统里的数据,在我们自己开发时,操作系统不会将内部数据暴露出来,不能直接访问,所以通过系统调用接口直接获取pid,ppid。
目录
- 1. 查看进程的第二种方法
- 2. 创建子进程
- 2.1 系统调用函数fork
- 2.2 fork的一般写法
- 2.3 fork的原理
- 3. 总结
1. 查看进程的第二种方法
在Linux系统中,不只有ps能够查看进程,还存在着一个动态目录proc,该目录存放了所有存在的进程,目录的名称。它会随着进程的改变而随时更新它的内容!
查看所有进程:
指令:ls /proc/

查看指定pid的进程文件:
指令:ls /proc/进程pid
如果想只查看这个目录我们可以:
指令:ls /proc/进程pid -dl
proc查看进程
当我们结束这个进程时,文件也会从proc中被删除
误删可执行程序时
在看完这个视频后,我们发现当我们在程序运行时,误删了可执行程序,进程不会被终止,但是在proc目录中的exe被标红并注明delete
在自行创建的进程中,我们只需要掌握好两个文件
cwd和exe
- cwd代表当前工作目录
- exe指向可执行程序的位置
默认情况下,进程启动所处的路径,就是当前路径,pwd指令其实就是从cwd中找到当前路径的!
当前工作目录是可以通过系统调用进行修改的:
指令:chdir ( " 路径 " )
我们只需要在代码编写时,加入这条指令我们就能更改当前工作目录
2. 创建子进程
2.1 系统调用函数fork
在Linux中,进程的创建方式有两种:
- 命令行中直接启动进程
- 通过代码创建
而在用代码创建进程时,实则是进行了系统调用,这里我们就得在学习一个系统调用函数fork!
函数:
fork
让我们来简单用man指令了解fork函数信息

fork的功能是创建一个子进程
让我们来简单实现以下fork


我们发现在fork之后函数printf调用了两次!!!
我们再来看看进程的ppid


- 说明了一个情况:fork之后,会创建子进程,并且子进程会和父进程一起进入后面的函数并且分别执行一次
2.2 fork的一般写法
结合目前: 只有父进程执行fork之前的代码(一定),fork之后,父子进程都要执行后续的代码!
- 因此我们推断
fork函数不仅会帮我们创建子进程而且它还有两个返回值,fork成功的时候,会有两个不同的返回值,给子进程返回0,给父进程返回子进程的pid。
首先我们来思考以下问题:
那么我们为什么要创建子进程?子进程的作用是啥?
- 我们想让子进程协作父进程完成一些工作,这些工作是单进程解决不了的,因此子进程的创建是为了协助父进程,因此父子进程做的是不一样的事情
我们怎么保证父子进程做的是不一样的事情呢?
- 我们可以通过判断
fork的返回值,判断谁是父,谁是子,然后让他们执行不同的代码片段
让我们来看一下fork的一般写法
1 #include<stdio.h>2 #include<sys/types.h>3 #include<unistd.h>4 5 int main()6 {7 printf("i am a process, 我的pid: %d\n", getpid());8 9 10 pid_t id = fork();11 12 if(id < 0) return 1;13 14 else if(id == 0)15 {16 // child17 while(1)18 {19 printf("我是子进程: pid: %d, ppid: %d, ret: %d, 我正在执行下载任务 \n",getpid(),getppid(),id);20 sleep(1);21 }22 }23 24 else25 {26 // parent27 while(1)28 {29 printf("我是父进程: pid: %d, ppid: %d, ret: %d, 我正在执行播放任务 \n",getpid(),getppid(),id);30 sleep(1);31 }32 }33 }

我们可以看到明明我们的fork只使用了一个变量接收但是出现了两个返回值
2.3 fork的原理
关于fork这个函数的原理,我们依然抛出几个问题
- fork干了什么事情?
- 为什么fork会有两个返回值?
- 为什么fork的两个返回值,会给父进程返回子进程pid,给子进程返回0?
- fork之后父子进程谁先运行?
- 如何理解同一个变量会有不同的值?
fork干了什么事情?
fork创建子进程,系统中会多一个子进程
- 以父进程为模板,为子进程创建PCB
- 但是你今天创建的子进程,是没有代码和数据的!!!目前和父进程共享代码和数据!!
- 所以,
fork之后,父子进程会执行一样的代码

为什么fork的两个返回值,会给父进程返回子进程pid,给子进程返回0?
在用进程中,一个父进程可能会有多个子进程,但是子进程永远都只有一个父进程,所以
父 :子 只会是 1 :n,为了能够更好的管理这些子进程,就必须返回具有唯一性的pid。但是子进程会很容易找到父进程,所以返回0表示成功即可!!
fork之后父子进程到底谁先运行?
创建完成子进程,只是一个开始,创建完成子进程之后,系统的其他进程,父进程和子进程,接下来要被调度执行的,当父子进程的PCB都被创建并在运行队列中排队的时候,哪一个进程的PCB先被选择调度,那个进程就先运行!!
- 但是PCB的选择调度是由操作系统自主决定(由各自PCB中的调度信息(时间片,优先级等)+调度器算法共同决定)
- 所以我们不确定父子进程到底谁先运行
最后为什么fork会有两个返回值?
如果一个函数到达了return,那么他的核心工作是否完成?
- 答案很显然是的,所以。。。

最后在fork之后代码共享,所以return也会被共享进入父子进程,并在父子进程中分别执行,所以在fork函数return之前,父子进程就已经分流,因此就会产生两个返回值!
如何理解同一个变量会有不同的值?
同一个函数有两个返回值是因为fork后两个进程都被调度了,但是同一个变量会有不同的值?该如何理解?
首先我们思考一下,如果我们杀掉子进程,父进程还会存在嘛?杀掉父进程呢?
分析父子进程是否独立
由此,我们可以得出结论:进程之间运行的时候,是具有独立性的,杀掉父进程不会影响子进程!反之也是!
- 进程的独立性,首先是表现在有各自的PCB进行之间不会互相影响,代码本身是只读的,不会影响,数据父子是会修改的!代码共享,数据各个进程都会写时拷贝私有一份!
- 变量id是父进程定义的变量,保存数据,返回的时候发生写时拷贝,不同
的进程执行的代码中的变量id获取的值不同,所以id在父进程和子进程中值不同
3. 总结
fork函数的内容远不只有这么一点,但是理解这五个问题能快速帮助我们,简单理解这个函数,了解fork的原理!关于如何创建子进程我们就讲到这里!
谢谢大家支持本篇到这里就结束了

相关文章:
Linux进程——进程的创建(fork的原理)
前言:在上一篇文章中,我们已经会使用getpid/getppid函数来查看pid和ppid,本篇文章会介绍第二种查看进程的方法,以及如何创建子进程! 本篇主要内容: 查看进程的第二种方法创建子进程系统调用函数fork 在开始前ÿ…...
ICode国际青少年编程竞赛- Python-1级训练场-路线规划
ICode国际青少年编程竞赛- Python-1级训练场-路线规划 1、 Dev.step(3) Dev.turnLeft() Dev.step(4)2、 Dev.step(3) Dev.turnLeft() Dev.step(3) Dev.step(-6)3、 Dev.step(-2) Dev.step(4) Dev.turnLeft() Dev.step(3)4、 Dev.step(2) Spaceship.step(2) Dev.step(3)5、…...
uniapp微信小程序1rpx border在某些手机机型上边框显示不出来解决方案
小程序在ios系统中,如果border小于1px的情况下,border就可能显示不全(可能少了上下左右任意一边) 只需要加一个::after或::before伪类,使用绝对定位定在原来元素上边就不会产生问题了! .d_card_line1_tag { padding: 1rpx 14r…...
Linux mkfs.ext2命令教程:如何创建ext2文件系统(附实例详解和注意事项)
Linux mkfs.ext2命令介绍 mkfs.ext2是Linux系统中用于创建ext2文件系统的命令。它的作用是在指定的设备上创建一个ext2文件系统,使该设备能够存储文件和目录。创建ext2文件系统的过程包括以下几个步骤。 Linux mkfs.ext2命令适用的Linux版本 mkfs.ext2命令在大多…...
基于Springboot的校园招聘系统(有报告)。Javaee项目,springboot项目。
演示视频: 基于Springboot的校园招聘系统(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构&…...
将 Vue、React、Angular、HTML 等一键打包成 macOS 和 Windows 平台客户端应用
应用简介 PPX 基于 pywebview 和 PyInstaller 框架,构建 macOS 和 Windows 平台的客户端。本应用的视图层支持 Vue、React、Angular、HTML 中的任意一种,业务层支持 Python 脚本。考虑到某些生物计算场景数据量大,数据私密,因此将…...
使用 MobaXterm 链接 Ubuntu(Windows子系统)
MobaXterm_Personal_22.1 Ubuntu(Windows子系统)...
QT设计模式:代理模式
基本概念 代理模式(Proxy Pattern)是一种结构型设计模式,它允许你提供一个代理对象,以控制对其他对象的访问。 代理通常在客户端和实际对象之间充当中介,用于控制对实际对象的访问(如登录控制)…...
独热编码One-Hot是什么?在实际应用中具体是如何存储的?
One Hot编码是一种常用的文本或类别数据编码方式,尤其在自然语言处理和机器学习中。在One Hot编码中,每个词(或类别)会被表示为一个二进制的向量,这个向量的长度等于词汇表(或类别总数)的大小&a…...
计算机视觉与深度学习实战之以Python为工具:基于GUI搭建通用视频处理工具
注意:本文的下载教程,与以下文章的思路有相同点,也有不同点,最终目标只是让读者从多维度去熟练掌握本知识点。 下载教程:计算机视觉与深度学习实战-以MATLAB和Python为工具_基于GUI搭建通用视频处理工具_项目开发案例教程.pdf 一、引言 随着计算机视觉和深度学习技术的飞速…...
18.Docker学习
1.Docker应用场景 Docker借鉴了标准集装箱的概念。标准集装箱将货物运往世界各地,Docker(模板)将软件运往各个环境(测试环境和生产环境拉取镜像(实例)),相当于是一个模子刻出来的 …...
树莓派4b红外检测
1.红外检测连接图 2.红外检测工作原理 红外传感器的工作原理类似于物体检测传感器。该传感器包括一个红外LED和一个红外光电二极管,因此通过将这两者结合起来,可以形成一个光耦合器。 红外LED是一种发射红外辐射的发射器。该LED看起来与标准LED相似&a…...
大模型的不足与解决方案
文章目录 ⭐ 不具备记忆能力 上下文窗口受限⭐ 实时信息更新慢 新旧知识难区分⭐ 内部操作很灵活 外部系统难操作⭐ 无法为专业问题 提供靠谱的答案⭐ 解决方案的结果 各有不同的侧重 在前面三个章节呢,为大家从技术的角度介绍了大模型的历程与发展,也为…...
Java中使用FlatBuffers实现序列化
Java 中的 FlatBuffers有助于高速数据序列化/反序列化,消除解析开销。它由 Google 开发,为跨平台数据交换提供无模式、内存高效的解决方案。 Java 开发人员可以利用其直接内存访问来实现最佳性能和最小内存占用,从而提高应用程序速度、可扩展…...
[图解]SysML和EA建模住宅安全系统-02
1 00:00:00,900 --> 00:00:02,690 这个就是一个块定义图了 2 00:00:03,790 --> 00:00:04,780 简称BDD 3 00:00:05,610 --> 00:00:08,070 实际上就是UML里面的类图 4 00:00:08,080 --> 00:00:09,950 和组件图的一个结合体 5 00:00:13,150 --> 00:00:14,690 我…...
2024年北京服贸会媒体邀约资源有哪些?
传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 2024年北京服贸会(中国国际服务贸易交易会,简称CIFTIS)作为中国重要的国际性服务贸易盛会,会吸引众多媒体的关注和参与。媒体邀约资源通常…...
大语言模型LLM入门篇
大模型席卷全球,彷佛得模型者得天下。对于IT行业来说,以后可能没有各种软件了,只有各种各样的智体(Agent)调用各种各样的API。在这种大势下,笔者也阅读了很多大模型相关的资料,和很多新手一样&a…...
Alibaba Cloud Linux 安装mysql及注意事项
1.安装mysql #1.运行以下命令,更新YUM源。 sudo rpm -Uvh https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm#2.(可选)当操作系统为Alibaba Cloud Linux 3时,执行如下命令,安装MySQL所需的库文件…...
设计模式——工厂模式(Factory)
工厂模式(Factory Pattern)是一种常用的设计模式,它提供了一种封装创建对象过程的方法。通过工厂方法或工厂类,你可以将对象的创建与使用分离,使得代码更加灵活和可维护。工厂模式主要分为三种类型:简单工厂…...
NVIDIA Omniverse Cloud API支持数字孪生开发,可解决复杂AI问题 | 最新快讯
在全球范围内,价值超过 50 万亿美元的重工业市场,正在竞相实现数字化。 基于此,为帮助数字孪生技术更好地赋能千行百业,AI 企业 NVIDIA 在架构底层算力的同时,也搭建了 NVIDIA AI Enterprise 和 Omniverse 两大平台。 …...
【软考高级架构】论文范文21——论Kappa架构在大数据平台中的设计与应用
论Kappa架构在大数据平台中的设计与应用 摘要 随着大数据技术的快速发展,传统Lambda架构因需要同时维护批处理和流处理两套系统,导致开发复杂度高、数据口径不一致、运维成本大等问题日益突出。Kappa架构作为一种精简的统一处理范式,通过将数据全部视为流、以消息队列为核…...
Perplexity体验真相曝光:92%用户忽略的3个隐藏缺陷及2024最新优化方案
更多请点击: https://intelliparadigm.com 第一章:Perplexity用户评论汇总 主流平台高频反馈主题 用户在Reddit、Product Hunt及App Store等平台对Perplexity的评价呈现显著两极分化:专业用户高度认可其引用溯源能力与无幻觉回答质量&#…...
GitLab团队协作实战:从分支策略到CI/CD流水线优化指南
1. 项目概述:为什么需要一个专属的GitLab使用指导?在团队协作开发中,版本控制系统是基石,而GitLab作为集代码托管、CI/CD、项目管理于一体的DevOps平台,其重要性不言而喻。然而,对于许多新加入团队的开发者…...
AI 测试必修课:深入理解 LLM 的 Token、上下文与温度参数
一位资深测试工程师的血泪忠告:“你花三个月搭建的测试框架崩溃了——不是因为代码逻辑有bug,而是因为昨天 temperature 是 0 的时候模型输出是‘PASS’,今天同样的代码、同样的输入,模型说‘FAIL’。你以为温度设成 0 就稳了?天真。” 这是一篇写给 AI 测试工程师、LLM 应…...
鼎讯 SZT-1000A:交通网络多合一智能测试仪
铁路、高速公路通信网络业务密集、链路复杂,集传输、监控、收费于一体,对测试设备的集成度、便携性、精准度要求极高。鼎讯 SZT-1000A 以太网测试仪,以 “一机多能、超轻便携” 的优势,成为交通领域网络安装、调试、运维的核心利器…...
Chrome 90+ 跨域请求突然失败?手把手教你排查 strict-origin-when-cross-origin 这个‘新’策略
Chrome 90 跨域请求突然失败?从原理到实战的完整解决方案 最近不少开发者反馈,Chrome浏览器升级到90版本后,原本正常运行的前端项目突然出现跨域请求失败的问题。控制台只显示一个模糊的strict-origin-when-cross-origin错误,让人…...
通过用量看板深度分析,回顾团队月度大模型API开销明细
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 通过用量看板深度分析,回顾团队月度大模型API开销明细 对于团队管理者而言,清晰、透明地掌握大模型API的使…...
Arm架构AMU性能监控原理与实践指南
1. Arm架构活动监视器(AMU)核心原理活动监视器(Activity Monitors Unit, AMU)是Armv8/v9架构中用于性能监控的关键硬件模块。作为处理器微架构的一部分,AMU通过专用硬件计数器实时采集CPU执行过程中的各类性能事件数据。与传统的性能监控单元(PMU)相比,A…...
AI Agent Harness Engineering 与组织结构重塑:未来公司将变成什么样
AI Agent Harness Engineering 与组织结构重塑:未来公司将变成什么样 摘要/引言 你有没有在深夜刷到过这样的“科技黑话式”创业视频?创始人拍着桌子喊:“我们公司90%的活都是AI干的!产品上线从3个月缩短到3天!利润率翻了10倍!”旁边的工位要么是空的,要么坐着手忙脚乱…...
初次使用Taotoken从注册获取Key到完成第一次API调用的全流程指引
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 初次使用Taotoken从注册获取Key到完成第一次API调用的全流程指引 本文旨在为初次接触Taotoken平台的开发者提供一份清晰的入门指南…...
