【lesson10】fork创建进程的现象解答

文章目录

  • fork现象
  • fork问题

fork现象

我们先来看一段代码。
在这里插入图片描述
大家觉得这段代码的printf会打印几次?
结果:
在这里插入图片描述
我们可以清楚的看到,第二个printf打印了2次。
我们再来看一段不可思议的代码:
在这里插入图片描述
运行结果:
在这里插入图片描述
我们可以看到这res竟然有两个值。
从上面我们可以得出结论,fork之后变成了两个进程一个是父进程,一个是子进程。
代码证明:
在这里插入图片描述

运行结果:
在这里插入图片描述
我们可以看到确实fork之后变成了两个进程。

由此我们可以的出结论:fork之后的代码是父子共享的,所以才会出现上面printf会被打印两次的现象。

我们创建子进程出来就是为了执行不同的代码逻辑,如果代码是共享的我们该如何执行不同的代码逻辑呢?
用以下方法解决:
之前我们学过fork在子进程和父进程中的返回值是不同的
父进程:返回子进程pid
子进程:返回0
创建子进程失败:返回-1

接下来就是解决上面问题的方法:
用分支语句解决。
在这里插入图片描述
运行结果:
在这里插入图片描述
我们可以看到确实解决了上面的问题。
我们让他们一直循环,看两个进程会不会同时进行
在这里插入图片描述
运行结果:
在这里插入图片描述
我们在用监测指令,查看两个进程:
在这里插入图片描述
我们可以看到Linux中确实存在2个这样的进程,上面是父进程,下面是子进程。
上面说明了:fork之后有两个不同的执行流,各自ret在父子进程中是不一样的。

fork问题

问题一为什么一份C语言代码,其中同一个变量会有不同的值?
下篇博客讲解
问题二为什么给子进程返回的是0,给父进程返回的是子进程的pid
首先我们会理解一个事情:
父进程和子进程的比例一定是一比多的,我们可以理解为一个父亲可以有多个儿子,但是一个儿子一定只有一个父亲。
父进程 : 子进程 = 1 : n
其次举个例子
比如张三有四个孩子子,为了区分他们,分别给孩子们取了名字,小明,小花,小华和小美。有一天小明的老师把张三叫到学校,说小明这次考试不好等等。张三回到家会叫小名你给我过来,还是会叫孩子你给我过来,肯定是叫名字因为有四个孩子如果叫孩子你给我过来歧义太大。
最后推广:
所以上面的例子推广到fork中,就明白为什么fork给父进程返回的是子进程的pid,是为了更好的区分他们。
问题三:为什么fork会有两个返回值?
首先我们要理解一个问题:
创建进程的时候,OS要做什么?
本质就是系统多了一个进程,所以OS要新建一个PCB(task_struc)来管理进程。
在这里插入图片描述
子进程PCB(task_struct)结构体的内部属性,要以父进程的PCB结构体为模板创建。
例子:比如你和你父母的DNA一定是相似度很高的。
其次我们要理解:
当fork已经准备return了,fork的核心代码执行完了吗?
我们都知道进程是用PCB结构体管理的,而PCB结构体是存放在链表中的,是以链表的形式管理起来的
在这里插入图片描述
那么CPU要调度进程是直接从链表中调度进程吗?
不是的,在Linux中还存在一种运行队列,当进程要被调度是先要被加载到运行队列中。
在这里插入图片描述
当进程加载到运行队列中执行完就会被干掉。
在这里插入图片描述

所以操作系统和CPU运行某个进程,本质从PCB结构体形成的队列中挑选一个PCB结构体,来执行它的代码和数据,进程调度变成了在PCB结构体的队列中选择一个进程的过程。
只要想到进程优先想到对应的PCB结构体。
在这里插入图片描述
而当fork准备return的时候,核心代码数据其实早已经跑完了。
当我们到return的时候其实,父进程和子进程早就已经进入到运行队列中
在这里插入图片描述
所以当运行到return时父进程和子进程分别会执行自己return语句,所以就会有两个返回值。
问题四:fork()有两个返回值,意味着会被保存两次吗?
下次博客揭晓。
问题五:父子进程被创建出来了,哪一个进程先被运行完呢?
这个并不一定,因为一个进程并不一定会一直被CPU调度,可能CPU运行个10毫秒就继续运行另一个进程
所以谁先被运行或者先运行完,由操作系统的调度器决定,不由人为决定。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面向面试知识-Redis

面向面试知识-Redis 什么是Redis 运行于内存的基于key-value的非关系型数据库。 一款开源的内存数据结构存储,用作数据库、缓存、消息代理等。(可以基于Redis实现分布式锁、以及消息队列) 发布订阅?? 对数据类型的操…

(高阶) Redis 7 第15讲 布隆过滤器 BitMap篇

面试题 如何快速准备判断某一数据在海量数据中存在了解布隆过滤器吗安全网址判断,黑名单校验,识别垃圾邮件白名单校验,识别合法用户?理论 由一个初始值都为0的 bit数组和多个哈希函数构成,用来快速判断集合中是否存在某个元素 设计思想 目的减少内存占用方式不保存数据信…

Python 运行代码

一、Python运行代码 可以使用三种方式运行Python,如下: 1、交互式 通过命令行窗口进入 Python 并开始在交互式解释器中开始编写 Python 代码 2、命令行脚本 可以把代码放到文件中,通过python 文件名.py命令执行代码,如下&#xff…

Java 核心技术卷 I —— 第2章 Java 编程环境

文章目录 2.1 安装 Java 开发工具包(*)2.2 使用命令行工具2.3 使用集成开发环境(*)2.4 JShell 2.1 安装 Java 开发工具包(*) 2.2 使用命令行工具 ​ 打开终端窗口,进入 Java 的 bin 目录&…

测试与FastAPI应用数据之间的差异

【squids.cn】 全网zui低价RDS,免费的迁移工具DBMotion、数据库备份工具DBTwin、SQL开发工具等 当使用两个不同的异步会话来测试FastAPI应用程序与数据库的连接时,可能会出现以下错误: 在测试中,在数据库中创建了一个对象&#x…

Centos7安装wps无法打开及字体缺失的问题解决

在centos7上安装了最新的wps2019版本的wps-office-11.1.0.11704-1.x86_64.rpm,生成了桌面图标并信任,可以新建文件,但是软件无法打开。在终端执行如下命令,用命令行启动wps: cd /opt/kingsoft/wps-office/office6/ ./…

Web ui自动化测试框架总结

【软件测试面试突击班】如何逼自己一周刷完软件测试八股文教程,刷完面试就稳了,你也可以当高薪软件测试工程师(自动化测试) 实施过了web系统的UI自动化,回顾梳理下,想到什么写什么,随时补充。 首…

下载水果FLStudio21.2软件安装更新教程

编曲是一种对音乐创作过程中涉及的元素和步骤进行组织和安排的艺术形式。对于想要学习编曲的人来说,以下是一些有用的建议: 1. 学习基础知识 在开始学习编曲之前,你需要掌握一些基础知识,例如音乐理论、乐器演奏和数字音乐制作技…

代码随想录算法训练营 动态规划part12

一、最佳买卖股票时机含冷冻期 309. 买卖股票的最佳时机含冷冻期 - 力扣&#xff08;LeetCode&#xff09; public class Solution {public int maxProfit(int[] prices) {int len prices.length;if (len < 2) {return 0;}int[] dp new int[3];dp[0] 0;dp[1] -price…

PHP8中调换数组中的键值和元素值-PHP8知识详解

在php8中使用array_flip()函数可以调换数组中的键值和元素值。 在PHP8中使用array_flip()函数可以调换数组中的键值和元素值&#xff0c;示范代码如下&#xff1a; <?php$stu array("子涵"> 001,"欣怡"> 002,"梓涵">003,"晨曦…

雷达编程实战之幅度与相位标定

车载毫米波雷达的角分辨率是雷达的一项重要性能指标&#xff0c;为了正确的解算目标的角度&#xff08;目标的方向角&#xff0c;俯仰角&#xff09;信息&#xff0c;雷达往往在出厂之前需要将不同信号通道&#xff08;TX>RX&#xff09;在面对相对零度角目标时&#xff0c;…

LeetCode 75 - 01 : 最小面积矩形

type pair struct{x, y int }func minAreaRect(points [][]int)int{mp : map[pair]struct{}{}// 将二维数组中的坐标映射到map中for i : range points{mp[pair{points[i][0], points[i][1]}] struct{}{}}// 将结果设置为一个最大值&#xff0c;防止影响求最小值的逻辑res : ma…