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

目录

前言

一、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.mfbz.cn/a/326372.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

05--多表操作

1、多表操作 现实生活中,(班级)实体与(学生)实体之间肯定是有关系的,那么我们在设计表的时候,就应该体现出(班级)表与(学生)表之间的这种关系&am…

学习视频一些杂乱的东西

文章目录 ref获取dom元素监听深层的某个属性? 可选链操作符 和 ?? 双问号表达式v-slot 语法糖作用域插槽动态插槽 初始化数组骚操作数字滚动 -> gsapstyle妙招新奇的原型链 object.createB站笔记链接JS相关设计模式ajaxsvgvue3scsswebpack内存泄漏 ref获取dom元素 直接给…

Angular系列教程之组件

文章目录 前言组件的基本概念组件与指令的关系在模板中使用组件总结 前言 在Angular中,组件是构建Web应用程序的核心单元。它们允许我们将UI划分为独立且可重用的部分,并通过数据绑定和事件处理等机制来实现交互性。本文将介绍Angular组件的基本概念&am…

如何公网远程访问Axure RP制作的本地web页面【内网穿透】

文章目录 前言1.在AxureRP中生成HTML文件2.配置IIS服务3.添加防火墙安全策略4.使用cpolar内网穿透实现公网访问4.1 登录cpolar web ui管理界面4.2 启动website隧道4.3 获取公网URL地址4.4. 公网远程访问内网web站点4.5 配置固定二级子域名公网访问内网web站点4.5.1创建一条固定…

❤ Uniapp使用三( 打包和发布上线)

❤ Uniapp使用三( 打包和发布上线) 一、介绍 什么是 uniapp? uniapp 是一种基于 Vue.js 的多平台开发框架,它可以同时用于开发安卓、iOS、H5 等多个平台。因此,只需要写一次代码就可以在多个平台上运行,提高了开发效率。 打包…

蓝桥杯 彩灯与任务

题目描述 输入样例 5 5 5 4 3 3 9 R 1 C 4 R 5 A 3 R 2 输出样例 5 3 3 思路 第一眼读不懂旋转是啥意思&#xff0c;根据样例连蒙带猜猜出来&#xff0c;其实就是把整个数组中的挪动几个位置。也很自然的按照题意写出来如下代码&#xff1a; #include <iostream> using…

如果你正在学自动化测试,那么请你仔细看完这篇文章

接触了不少同行&#xff0c;由于他们之前一直做手工测试&#xff0c;现在很迫切希望做自动化测试&#xff0c;其中不乏工作5年以上的人。 本人从事软件自动化测试已经近5年&#xff0c;从server端到web端&#xff0c;从API到mobile&#xff0c;切身体会到自动化带来的好处与痛楚…

kylin集群负载均衡(kylin3,hbaseRIF问题)

hbase历险记 目录 hbase历险记 寻找问题 分析原因 解决方案 方案1&#xff08;资源问题、失败&#xff09; 方案2&#xff08;成功&#xff09; 寻找问题 不知道你是不是有这样的疑惑。我kylin是个单机&#xff0c;我使用的hbase是个集群&#xff0c;但内存全在某一台机…

高并发缓存问题分析以及分布式锁的实现

一,场景概述: 在高并发的环境下,比如淘宝,京东不定时的促销活动,大量的用户访问会导致数据库的性能下降,进而有可能数据库宕机从而不能产生正常的服务,一般一个系统最大的性能瓶颈&#xff0c;就是数据库的io操作,如果发生大量的io那么他的问题也会随之而来。从数据库入手也是…

Python基础知识:整理13 利用pyecharts生成折线图

首先需要安装第三方包pyecharts 1 基础折线图 # 导包&#xff0c;导入Line功能构建折线图对象 from pyecharts.charts import Line # 折线图 from pyecharts.options import TitleOpts # 标题 from pyecharts.options import LegendOpts # 图例 from pyecharts.options im…

CSAPP阅读笔记-程序的机器级表示

程序的机器级表示 计算机执行机器代码&#xff0c;用字节序列编码低级的操作&#xff0c;包括处理数据、管理内存、读写存储设备上的数据&#xff0c;以及利用网络通信。编译器基于编程语言的规则、目标机器的指令集和操作系统遵循的惯例&#xff0c;经过一系列的阶段生成机器…

微信小程序---如何创建分包

1.在项目根目录中&#xff0c;创建分包的根目录&#xff0c;名为subpkg&#xff0c;这个名字可以自己定义 2.在 pages.json 中&#xff0c;和 pages 节点平级的位置声明 subPackages 节点&#xff0c;用来定义分包相关的结构&#xff1a; 3.在分包目录&#xff0c;点击右键新建…

进程切换和是Linux2.6内核中进程调度的算法

正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 进程切换 进程并发就需要做到进程切换&#xff0c;一个CPU一套寄存器但是需要运行的进程有很多…

发票系统对接诺诺平台

诺诺平台判断设备不在线&#xff0c;导致开票失败 代码方面优化&#xff1a;调用接口的时候&#xff1a;是否先调用在线状态检测接口&#xff0c;确认开票设备是在线的状态 &#xff0c;在调用诺诺平台&#xff0c;不在线直接拦截&#xff1b;例如&#xff1a;这个原理就类似于…

DIYgif表情包怎么做?gif表情包制作方法分享

Gif表情包是我们生活交流中必不可少的一种方式&#xff0c;能够表达自己的心情&#xff0c;也能够调节气氛。平时我们的gif表情包都是从网上下载或是别人发送的&#xff0c;那么我们怎么自己DIYgif表情包呢&#xff1f;这时候&#xff0c;用qq表情在线制作&#xff08;https://…

在IntelliJ IDEA中集成SSM项目

SSM项目&#xff1a;springMVC为控制器、spring 为事务层、 MyBatis 负责持久 首先看下集成后项目结构&#xff1a; 1、打开IntelliJ IDEA&#xff0c;点击 "File" -> "New" -> "Project"。 点击Finish&#xff0c;此时我们就已经创建了一…

图书信息管理系统

1.程序组成&#xff1a; 源文件&#xff1a;test.cpp&#xff0c;源.cpp 头文件&#xff1a;test.h 2.功能实现&#xff1a; 系统以菜单方式工作&#xff0c;图书信息录入功能&#xff0c;图书信息浏览功能&#xff0c;查询功能删除功能价格排序修改图书信息程序加密 &…

手机更换社保证照片教程来啦,速速查收!

&#x1f4cc;线上直接搞定很简单&#xff01; 没有申领社保卡的姐妹们可以自己申领&#xff01; 已有社保卡的姐妹可以先挂失然后再申领&#xff01; &#x1f64c;教程 线上更换社保证&#xff1a; 1️⃣打开「掌上12333」&#xff0c;找到电子社保卡 2️⃣点击社保卡申领&am…

关于影视字幕翻译哪个公司比较专业?

现如今&#xff0c;影视剧作为跨文化交流的重要桥梁&#xff0c;正日益受到中国观众的热爱。因此也催生了影视字幕翻译的需求。那么&#xff0c;如何做好影视作品字幕翻译&#xff0c;哪个公司在影视字幕英译中更为专业&#xff1f; 我们知道&#xff0c;字幕翻译是涉外影视作品…