Linux------进程的fork()详解

news2024/11/20 2:25:55

目录

前言

一、fork()的使用

二、fork()的返回值

我们为什么要创建子进程?

父进程与子进程的分流

三、fork的一些难理解的问题

1.fork干了什么事情?

2.fork为什么会有两个返回值 

3.fork的两个返回值,为什么会给父进程返回子进程pid,给子进程返回0?

4.fork之后,父子进程谁先运行?

5.如何理解同一个变量,会有不同的值??


前言

在之前,我们学习了进程的概念以及命令行启动进程,今天我们来学习另一种进程创建方法:用代码创建进程。

这里我们简单回顾一下,进程 = 可执行程序+task_struct对象

创建一个进程,在系统中要申请内存,保存当前进程的可执行程序 + task_struct对象,并将 task_struct对象添加到进程列表

一、fork()的使用

我们在命令行man fork 看一下fork函数的用法与作用。 

根据图片可以得到fork会创建一个子进程, 在执行fork()过后,会从一个执行流变成两个执行流,这两个执行流都会执行后续的代码。这里说起来还是有点抽象,我们直接上代码试一试。代码如下。

我们发现明明我们只写了两句打印代码,却输出了三句,fork之后,打印代码执行了两遍。 还发现本身进程为21554,现在还多了一个进程为21555。

我们打印更多消息看一下 

执行看一看效果,这里我们发现,调用fork()后,新生成的进程是当前进程的子进程。

现在我们可以总结一下结论:只有父进程执行fork之前的代码,fork之后,父子进程都要执行后面的代码

二、fork()的返回值

我们命令行  man fork 再来看一下fork的返回值。失败了返回-1,并且没有子进程被创建,如果成功,父进程返回子进程的PID,子进程返回0。这直接颠覆了我们的认知,为什么一个函数可以有两个返回值啊。

我们编辑代码,打印出来看看怎么回事。

 

我们发现确实如此,返回的值真的不一样 

虽然现在fork我们大概什么情况,但这里还有问题。

  1. 我们为什么要创建子进程?
  2. 我们创建子进程是为了让子进程和我们父进程做一样的事情吗?

我们为什么要创建子进程?

之前,我们学习C/C++的时候,根本就没听说过什么fork父进程子进程,这是因为当时我们的任务是线性的,只需要完成一件事就行了,现在,我们想让子进程协作父进程完成一些工作,这些工作是单进程解决不了的

举个例子,我最爱迅雷边下边播这个功能,我们想让一个进程去下载,另一个进程去播放,这样才可以达到我们的目标。

我们创建子进程,就是为了让子进程和父进程做不一样的事

但是,现在问题又来了,你如何保证他们两可以执行不同的代码呢?

父进程与子进程的分流

我们可以通过fork的返回值的不同,判断出谁是子谁是父,从而让他们执行不同的代码。

我们看一下结果,确实可以通过fork返回值的不同来分流。

大家知道了fork的分流,但是底层逻辑我们还不清楚,这是如何分流的呀。怎么来了两个返回值呢?这些我们在下一章讲。

三、fork的一些难理解的问题

1.fork干了什么事情?

fork之后,子进程是没有自己的代码和数据的,子进程会和父进程共享代码和数据,因此他们执行的是一样的代码。

fork之前的代码,子进程也可以看见,但是fork之后,eip(是寄存器,用来存储CPU要读取指令的地址,CPU通过EIP寄存器读取即将要执行的指令)指向的fork后续的代码,eip也会被子进程继承,因此子进程只会执行fork之后的代码。

2.fork为什么会有两个返回值 

fork是系统接口,本质上就是一个函数,在fork里面进行创建子进程,将子进程放入调度队列中。我们现在知道,fork之后,代码共享,这里指的在fork内部,代码就已经被共享了,也就是子进程已经被创建出来了,最后需要return返回。

父进程需要return,子进程也需要return,因此fork会有两个返回值。

3.fork的两个返回值,为什么会给父进程返回子进程pid,给子进程返回0?

在现实中,你生了五个儿女,你叫他们不能统一的叫儿子或者女儿,因为这样儿女不知道你叫的是哪个儿子哪个女儿,因此你需要叫他们大儿子,二儿子,大女儿来区分他们。而他们叫你爸爸,正常情况下爸爸只有一个,不需要做额外区分。

计算机也要标识出到底是哪一个儿子,由于父只有一个,而子进程可以有很多个,因此父进程返回子进程的pid,来标识你创建好的子进程pid是多少。子进程返回0,因为子进程只有一个父亲,不需要额外标识出来。

4.fork之后,父子进程谁先运行?

首先,fork创建完成子进程,这仅仅是一个开始,创建完成后,系统的其他进程,还有当前的父进程和子进程,是要被CPU调度执行的

当父子进程的PCB都被创建并在运行队列中排队的时候,哪一个进程先被CPU调度,哪一个进程就先运行,因此我们不确定这是由各自PCB的调度信息(时间片,优先级等)+调度算法自助决定。

5.如何理解同一个变量,会有不同的值??

要理解这个问题,我们得先知道父子进程是具有独立性的

比如之前我们提到的边下边播,你由于断网问题,下载停止了,但是只要你当前观看内容片段已经下载,播放就不会停止。

同理,如果我们fork之后,有了父子进程,父进程被杀掉,子进程也应该还在啊,或者子进程被杀掉,父进程应该也还在。如下。

杀死父进程,子进程仍在运行

杀死子进程,父进程仍在运行 

现在我们可以得知, 进程在运行的时候,无论什么关系,进程之间都具有独立性

这个独立性是如何做到的呢?

进程的独立性,首先表现在有各自的PCB。但是我们之前提到fork之后,子进程是没有代码和数据的,他和父进程共享代码和数据。代码本身是只读的,不会影响。但是数据是会修改的。因此父子进程代码共享,数据各自必须想办法私有一份。

这运用到了写时拷贝,如果数据值是一样的,那我就不做处理,如果数据不一样,那我子进程要想办法深拷贝一份数据,当子进程的值覆盖上去,这就完成了父子进程数据各自一份。

正是由于返回的时候发生了写时拷贝,因此同一个变量会有不同的值。 

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

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

相关文章

Linux Mii management/mdio子系统分析之六 fixed-mii_bus分析(mac2mac分析)

(转载)原文链接:[https://blog.csdn.net/u014044624/article/details/130674908] (https://blog.csdn.net/u014044624/article/details/130674908) 前面几章我们介绍了MDIO模块的大部分内容,针对mii_bus、mdio_bus、phy_device、p…

鸿蒙开发的前景趋势及薪资水平展望

随着科技的迅猛发展和数字化转型的推进,鸿蒙系统作为国内领先的分布式操作系统,已经在市场中崭露头角,展现出独特的技术优势和广阔的应用前景。对于开发者而言,掌握鸿蒙开发技能不仅意味着拥有更多的职业发展机会,还预…

Win10输入密码不满足密码策略要求的解决方法

在Win10电脑中用户输入密码的时候,收到了不满足密码策略要求的提示,导致用户不能成功设置密码。用户先打开Win10系统的组策略编辑器,点击关闭密码必须符合复杂性要求功能保存即可。以下小编将分享Win10密码不符合策略要求的解决方法步骤&…

Relation-Aware Graph Transformer for SQL-to-Text Generation

Relation-Aware Graph Transformer for SQL-to-Text Generation Abstract SQL2Text 是一项将 SQL 查询映射到相应的自然语言问题的任务。之前的工作将 SQL 表示为稀疏图,并利用 graph-to-sequence 模型来生成问题,其中每个节点只能与 k 跳节点通信。由…

Linux -- firewalld的富语言规则

1. Firewalld支持两种类型的NAT:IP地址伪装和端口转发。 (1)IP地址伪装 地址伪装(masquerade):通过地址伪装,NAT 设备将经过设备的包转发到指定接收方,同时将通过的数据包的源地址更改为其自己的…

WBTT:“Fair Launch”如何做到更加公平

铭文是一种全新的资产发行方案,它让非图灵完备的链上生态具备发行资产的能力,而铭文赛道的兴起也让比特币生态再次回到加密世界的中心。铭文市场的兴起,更被称之为“散户的狂欢”,因为这种“Fair Launch”的启动方式正在让所有参与…

Webpack 怎么实现按需异步加载模块

要弄懂这个问题,需要先来看关于webpack打包的3个问题。 三个问题 第一个问题 项目中的json文件,如何使用webpack进行处理? 如果我们希望把json文件当做静态配置,例如有如下json文件 {"version": "1.0.0"…

[Android]实现一个权限申请类

[Android]实现一个权限申请类 导言 在引入了动态权限申请之后,Android的权限申请就变得尤为繁琐,若是按照原有的方法一板一眼地进行申请,样板代码未免太多。因此本篇文章就使用ActivityResult API,来实现一个简单的权限申请类来帮…

国标视频监控平台EasyCVR如何通过接口调用下载设备录像文件

安防监控系统国标GB28181协议EasyCVR视频监控平台采用了开放式的网络结构,平台可支持Windows/Linux(CentOS ubuntu)/国产麒麟系统,能在局域网、公网、专网等复杂的网络环境中,将场景中分散的海量网络监控设备进行统一接入与汇聚管理&#xff…

USB Cable导致连接识别不良

2根USB线,连接USB2RS232芯片,有根线能够识别,另外一根不能识别。 好的线识别如下: 另外一根就不能识别

GZ036 区块链技术应用赛项赛题第1套

2023年全国职业院校技能大赛 高职组 “区块链技术应用” 赛项赛卷(1卷) 任 务 书 参赛队编号: 背景描述 随着消费需求的不断变化,消费者对食品安全的关注度越来越高,希望能参与食品供应链管理,让每个环节都透明化。但传统的供应链管理依靠纸张记录,保存数…

[自动驾驶算法][从0开始轨迹预测]:二、自动驾驶系统中常用的坐标系及相应的转换关系

自动驾驶中常见的坐标系与坐标转换 1. 传感器坐标系1.1 相机坐标系统1) 相机相关基础知识2) 相机各坐标系图像/像素坐标系相机坐标系像平面坐标系 3) 相机各坐标系之间的转换像平面坐标系到像素坐标系的转换(平移缩放变换)相机坐标系转像平面坐标系&…

Oracle基础查询介绍

1、oracle语句分为: DCL:数据控制语言,关键字有 grant、revoke 如:grant create table to test2; DDL:数据定义语言,关键字有 create、alter、drop、truncate 如:create table test1; DML&am…

接口测试用例设计 - 实战篇

一.接口测试流程 1.需求讨论 2.需求评审 3.场景设计 4.数据准备 5.执行 二.分析接口文档中哪些元素 1.接口名称 2.接口地址 3.支持格式 4&#xff0…

IDEA2023的激活与安装(全网最靠谱,最快捷的方式)

前言: 相信很多小伙伴已经开始了java的学习之旅,想要更快乐的学习当然少不了IDEA这个得力的开发工具软件。但是IDEA是付费的,免费版功能有太少,怎么才能既免费,又能使用上正式版呢!当然还是激活啦&#xf…

【昕宝爸爸小模块】深入浅出之JDK21 中的虚拟线程到底是怎么回事(一)

➡️博客首页 https://blog.csdn.net/Java_Yangxiaoyuan 欢迎优秀的你👍点赞、🗂️收藏、加❤️关注哦。 本文章CSDN首发,欢迎转载,要注明出处哦! 先感谢优秀的你能认真的看完本文&…

Leetcode22-旅行终点站(1436)

1、题目 给你一份旅游线路图,该线路图中的旅行线路用数组 paths 表示,其中 paths[i] [cityAi, cityBi] 表示该线路将会从 cityAi 直接前往 cityBi 。请你找出这次旅行的终点站,即没有任何可以通往其他城市的线路的城市。 题目数据保证线路…

【Macos系统】安装VOSviewer及使用VOSviewer教程!!以ESN网络的研究进行案例分析

【Macos系统】安装VOSviewer及使用VOSviewer教程 以ESN网络的研究进行案例分析 本文介绍如何安装和使用VOSviewer软件,并以ESN(Echo State Network)网络的研究为案例进行分析。利用VOSviewer对相关文献进行可视化分析,并深入了解…

最新可用GPT-3.5、GPT-4、Midjourney绘画、DALL-E3文生图模型教程【宝藏级收藏】

一、前言 ChatGPT3.5、GPT4.0、GPT语音对话、Midjourney绘画,文档对话总结DALL-E3文生图,相信对大家应该不感到陌生吧?简单来说,GPT-4技术比之前的GPT-3.5相对来说更加智能,会根据用户的要求生成多种内容甚至也可以和…

麒麟KYLINOS域名解析失败的修复方法

原文链接:麒麟KYLINOS域名解析失败的修复方法 hello,大家好啊!今天我要给大家介绍的是在麒麟KYLINOS操作系统上修复域名解析的方法。在日常使用中,我们可能会遇到由于系统配置问题导致的域名解析失败,这在内网环境下尤…