Linux学习之路 -- 进程篇 -- PCB介绍2 -- 标识符和进程创建

前面我们介绍了的进程的标识符,下面继续介绍进程标识符和进程创建的知识。

目录

一、进程创建

<1>fork函数的返回值

<2>创建子进程的目的

<3>代码共享

二、fork函数的相关问题

<1>为什么给父进程返回子进程的pid,给子进程返回0?

<2>fork函数为什么会返回两次?

<3> 为什么同一变量有不同的值(也就是上面死循环示例的id)?


一、进程创建

前面我们用fork来创建了一个子进程,这里fork()函数会返回两个值,在fork之后,fork后面的代码会被执行两次。父进程执行完后,子进程会重新从fork处开始执行代码(这两个的顺序没法确定,这是由操作系统的调度器决定的)。这里我们先从这个函数的返回值来看。

<1>fork函数的返回值

我们可以打开对应的手册观察fork的返回值

在man手册中,我们可以看见如果fork这个系统调用成功的话,对于父进程,如果创建成功,则fork函数就会返回子进程的pid,如果创建失败了,就返回-1。对于子进程,如果创建成功,fork函数就会返回0,如果不成功,则直接就没有该进程。

这里最令人疑惑的点是一个函数由两个返回值,但是这里涉及知识比较多,暂时先不讲,留到后面描述。

<2>创建子进程的目的

我们创建子进程是为了让父子进程执行不同的操作,这里我们可以用他们的返回值来实现该操作,

这里我用的是vscode,我们可以把远程终端(这里我的是云服务器链接到vscode,然后在vscode上编辑代码)链接到我们的vscode。这里根据返回值的不同,我们就可以实现不同进程执行不同的代码。

结果如上图,这里会有两个死循环交替进行(这里稍加解释一下,正常一个进程在cpu里面只会运行一段时间,一段时间过后,cpu就会执行下一个进程,这个其实就是时间片的概念。这也就是为什么我们会看到两个死循环交替进行的原因),这里我们就用两个返回值,使得系统执行不同的程序。

<3>代码共享

前面我们了解到,进程 = 可执行程序的代码和数据+内核数据结构, 这里的内核数据结构能由系统创建,但是由父进程创建的子进程哪里来的代码和数据呢? 

其实子进程指向的就是父进程的代码和数据,上面用两个死循环的程序其实都是父进程的代码,只不过这里被切成两部分(这里先这样理解),我们通过不同的返回值来实现不同进程执行不同代码块。这里的内核数据结构,也就是子进程的PCB,大部分也是从父进程的PCB上拷贝下来的,这也是子进程能指向和父进程同一块代码和数据的原因。

二、fork函数的相关问题

<1>为什么给父进程返回子进程的pid,给子进程返回0?

一个父进程可能由很多的子进程,父进程也需要子进程pid来唯一确定子进程,从而实现对子进程的控制,但是子进程就只有一个父进程,很好获取父进程的pid,而且子进程不太需要父进程的pid,所以给子进程的返回值是零。

<2>fork函数为什么会返回两次?

在调用fork这个函数后,内核会帮我们进行创建进程等等操作(这里不细讲),在执行到最后一行代码时,父子进程已经被创建,父子分别返回一次

<3> 为什么同一变量有不同的值(也就是上面死循环示例的id)?

在日常我们使用手机时,打开了许多个软件,如果我们关闭了一个软件,另外几个软件会不会受到影响呢?答案显然是不会。这里打开软件后,其实在系统中,这就已经变成了一个进程,如果我们关闭一个进程,其他进程也不会受到影响,所以我们可以得出一个结论,进程之间是互相不影响的,它们具有独立性。回到上面的问题,假如我们要修改一个变量时,为了保证进程的独立性,以我们把子进程或父进程指向变量的内存指针改变一下。下面我以子进程修改为例,画张图表示

具体过程,本篇文章不做详谈,这里涉及进程地址空间的知识,后面我会介绍。这里我们只要知道在linux中我们能用一个变量表示两个值就可以了。

关于标识符跟进程创建就先介绍到这里,如果希望本文对各位读者有些许帮助,如果文中有不当之处,还望各位大佬指正,谢谢!!!

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

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

相关文章

OpenHarmony开发-系统烧录

本文详细介绍了烧录OpenHarmony系统到开发板的操作流程。从基础的硬件准备和软件环境设置入手&#xff0c;详细说明了如何配置开发环境、构建系统镜像等过程&#xff0c;详细描述了烧录过程中的关键步骤&#xff0c;以及如何使用专用工具将OpenHarmony系统镜像传输到开发板。同…

CSS层叠样式表学习(引入方式)

&#xff08;大家好&#xff0c;今天我们将继续来学习CSS引入方式的相关知识&#xff0c;大家可以在评论区进行互动答疑哦~加油&#xff01;&#x1f495;&#xff09; 五、CSS的三种样式表 5.1 CSS的三种样式表 按照CSS样式书写的位置(或者引入方式)&#xff0c;CSS样式表可…

11-pyspark的RDD的变换与动作算子总结

目录 前言 变换算子动作算子 前言 一般来说&#xff0c;RDD包括两个操作算子&#xff1a; 变换&#xff08;Transformations&#xff09;&#xff1a;变换算子的特点是懒执行&#xff0c;变换操作并不会立刻执行&#xff0c;而是需要等到有动作&#xff08;Actions&#xff09;…

蓝桥杯每日一题:公约数(gcd)

题目描述&#xff1a; 给定两个正整数 a 和 b。 你需要回答 q 个询问。 每个询问给定两个整数 l,r&#xff0c;你需要找到最大的整数 x&#xff0c;满足&#xff1a; x 是 a和 b 的公约数。l≤x≤r。 输入格式 第一行包含两个整数 a,b。 第二行包含一个整数 q。 接下来…

并发包中的CompletableFuture介绍及使用示例

一、抛砖引玉——优化一个计数任务 1.1、需求&#xff1a;计算从1加累加到100的结果 1.1.1、普通的实现代码示例 package com.example.mavendemo.completablefuture;public class NormalTest {public static void main(String[] args) {long startTime System.currentTimeM…

C#开发中一些常用的工具类分享

一、配置文件读写类 用于在开发时候C#操作配置文件读写信息 1、工具类 ReadIni 代码 using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks;namesp…

LeetCode 1017. 负二进制转换

解题思路 相关代码 class Solution {public String baseNeg2(int n) {if(n0) return "0";String s"";while(n!0)if(Math.abs(n)%20){nn/(-2);ss0;}else{ss1; n (n-1)/(-2);}String t reverse(s);return t;}public String reverse(String s){Str…

ZYNQ学习Linux 基础外设的使用

基本都是摘抄正点原子的文章&#xff1a;《领航者 ZYNQ 之嵌入式Linux 开发指南 V3.2.pdf》&#xff0c;因初次学习&#xff0c;仅作学习摘录之用&#xff0c;有不懂之处后续会继续更新~ 工程的创建参考&#xff1a;《ZYNQ学习之Petalinux 设计流程实战》 一、GPIO 之 LED 的使…

自定义实现shell/bash

文章目录 函数和进程之间的相似性shell打印提示符&#xff0c;以及获取用户输入分割用户的输入判断是否是内建命令执行相关的命令 全部代码 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通俗易懂&#xff0c;风趣幽默&#…

(二)小案例银行家应用程序-创建DOM元素

● 上图的数据很明显是从我们账户数组中拿到了&#xff0c;我们刚刚学习了forEach&#xff0c;所以我们使用forEach来创建我们的DOM元素&#xff1b; const displayMovements function (movements) {movements.forEach((mov, i) > {const type mov > 0 ? deposit : w…

通用开发技能系列:Scrum、Kanban等敏捷管理策略

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 通用开发技能系列 文章&#xff0c;主要对编程通用技能 Scrum、Kanban等敏捷管理策略 进行学习 1.什么是敏捷开发 敏捷是一个描述软件开发方法的术语&#xff0c;它强调增量交付、团队协作、持续规划和持续学习…

github本地仓库push到远程仓库

1.从远程仓库clone到本地 2.生成SSH秘钥&#xff0c;为push做准备 在Ubuntu命令行输入一下内容 [rootlocalhost ~]# ssh-keygen -t rsa < 建立密钥对&#xff0c;-t代表类型&#xff0c;有RSA和DSA两种 Generating public/private rsa key pair. Enter file in whi…