Linux进程基础概念子进程的创建

        有着上一节我们对操作系统和冯诺依曼体系结构的理解,本篇我们便可以开始对 Linux 中的进程开始讲解。在本篇中对进程的基本概念进行了简单的介绍,然后通过对描述进程的 PCB,与 Linux 中的 task_struct 的详细讲解,使得对进程的概念有了一个更加详细的理解。然后接着又介绍了 task_struct 中的内部属性 pid 与 ppid(剩下的 task_ struct 内部属性将会在后面的文章给出),接着还介绍了进程的创建方式和子进程的创建,最后介绍了 proc 查看当前进程信息数据。

目录如下:

目录

1. 进程的基础概念

1.1 基本概念

1.2 描述进程 —— PCB

1.3 task_struct

2. 进程的进一步深入了解

2.1 tast_struct 的内部属性

2.2 进程创建的方式

2.3 fork 创建子进程

2.4 proc 查看进程

1. 进程的基础概念

1.1 基本概念

        进程在课本中的概念为:程序的一个执行实例,正在执行的程序。

        进程的内核观点:担当分配系统资源(CPU时间、内存)的实体(对于这个概念的认识,目前还不是清晰)。

        对于以上的两种概念来说,其实理解起来都相对枯燥,接下来我们将从内核数据结构展开,来对进程进行更加详细的剖析。

1.2 描述进程 —— PCB

        进程中的信息被放入到一个叫做进程控制块数据结构中,我们可以理解为进程属性的集合,课本上称为 PCB。如下图:

        如上图所示,当我们对电脑开机,电脑会首先将磁盘中的操作系统加载到内存中,操作系统在内存中也是需要占有一定的空间的。当我们想要使用某些程序的时候,会从磁盘中将该程序的代码和数据加载到内存中,但是目前这样还不能算是程序(进程),这仅仅只是进程的程序和数据,进程还需要被我们的操作系统所管理,所以在操作系统中还存在一个内核数据结构PCB(process control block)用来表征在加载在内存中的每个程序,这个 PCB 结构体中存在一个进程的所有属性,指向下一个 PCB 的 next 指针,以及该进程代码数据在内存中的位置,内存指针。

        当我们需要加载某个进程的时候,我们将在操作系统的内核数据结构中的插入一个新的 PCB 数据结构,然后将该进程的各种属性描述进该数据结构,当我们不在需要使用该进程的时候,我们就先将该进程的代码和数据先释放掉,然后将对应的 PCB 结构体给删除掉。

        所以对以上的总结一个进程一定会有一个对应的 PCB进程 = PCB + 对应的代码和数据,我们对进程的管理并非对内存中的数据代码做管理,而是对进程的 PCB 进行管理

1.3 task_struct

        对于 PCB 的实现,在不同的操作系统下存在不同的实现方式,如我们在 Linux 系统下对于 PCB 的实现为 task_struct 结构体。接下来给出一个程序在 Linux 系统下的调度简图:

        如上图所示,在操作系统中存在一个 task_queue 队列用于对 task_struct 结构体进行排队,当排到那个 task_struct 的时候,就会从内存中找到对应的代码和数据将其加载到 CPU 中进行处理,以此的排队顺序,分别分时的对每个进程进行处理。

2. 进程的进一步深入了解

        在上文中,我们已经介绍了进程的基本概念,以及描述的进程的 PCB,同时还有在 Linux 下的 PCB 结构体 task_struct,在下文中,我们还会围绕 task_struct 进行更加深入的探讨。

2.1 tast_struct 的内部属性

        接着我们来讨论 task_struct 中的内部属性,首先我们是关于程序的启动,如下:

        当我们在程序中写出一个可执行文件,当我们开始执行的时候,其实就是启动了一个程序,也就是进程。其实不仅是我们写出的可执行文件,我们的系统命令、可执行文件,在 linux 中的大部分执行操作,本质上都是在运行进程。

        现在我们开始查看 task_struct 中有关进程的属性,如下所示。

        每一个进程都有自己的唯一标识符,叫做进程pid,执行如下指令就可以查看我们进行从pid:

        进程之间的区分就是使用进程的唯一标识符:pid,获取 pid 的方法不仅仅只有通过外部指令能获取到进程的 pid,我们还可以在进程代码中标识出自己的 pid,此操作需要调用系统调用接口 getpid,如下:

        关闭进程的方式:通常我们关闭一直运行的进程,除了使用 ctrl + c,还可以使用另一个指令,kill -9 [进程的pid],如下:

        如上所示,我们使用 kill 指令将进程给终止掉了,kill -9 后面一定要跟进程的pid,当输入错误的 pid 的时候,便不能将进程的终止掉。

2.2 进程创建的方式

        接下来我们将从代码层面来揭露出进程创建的方式,我们在上文中发现每个进程都有着属于自己的进程标识符 pid,每个进程不仅有自己的 pid,还有对应的 ppid,也就是父进程的 pid,父进程的唯一标识符,如下:

        当我们执行如上代码之后,我们会发现,每一次运行同一个可执行文件(进程),得出的 pid 都是不一样的,而每一次进程对应的 ppid 却是一样的,其中 pid 每次不一样属于正常情况,因为每一次执行结束之后,后台也许还会运行别的进程,每一次给出进程的 pid 都是动态的。接下来,让我们看看 pid 为 12484 的进程是什么:

        通过如上操作,我们发现 pid 为 12484 的进程为 bash,也就是我们的命令行解释器,只要是在当前 Linux 环境中编译运行的可执行文件,其父进程都是 bash。

        那么接下来当我们想要创建一个进程的时候,我们该如何进行创建进程呢,在操作系统那篇 blog 中也已经指出,我们用户并不能直接在操作系统中创建出一个 task_struct,并不能直接使用 task_struct 创建出一个进程,但是我们可以使用系统提供的系统调用接口 fork,提供 fork 接口,我们就可以成功的在一个我们自己的进程中,创建出另一个进程,如下:

        如上图所示,当我们在代码中使用 fork 接口,原本代码中只存在一个语句打印 hello linux,但是在显示的程序中,我们发现,打印了两次 hello linux,并且在左边的监视窗口中,我们发现,过了一会又多了一个 myprocess 进程,并且该进程的 ppid 就是等于前面进程的 pid,所以我们可以得出新产生的这个进程就是由原来的进程产生的。

        还存在一个问题,为什么会打印两次 hello linux呢?原本在代码中只有一句打印 hello linux 的代码,这是因为使用 fork 接口之后,就会创建一个进程,本质上是系统中多出一个进程,多一个内核 task_struct,且该 task_struct 有着自己的代码和数据。在父进程的代码和数据是从磁盘中加载进来的,子进程的代码和数据又是从哪来呢?默认情况下,子进程的数据会继承父进程的代码和数据。所以会打印出两个 hello linux。

2.3 fork 创建子进程

        在上文中,我们已经发现使用 fork 可以创建出一个子进程,但是创建出子进程有什么作用呢?作用就是让子进程与父进程运行不一样的程序,提高效率。以下为 fork 的介绍:

        当我们使用 fork 创建子进程创建成功的时候,fork 会返回子进程的 pid 给父进程,返回 0 给子进程(自己),若创建子进程失败,就只能返回 -1。在这里我们会发现 fork 的不同,fork 的返回值有两个,我们在以往的学习中,关于 C/Cpp,其各种函数都是只返回一个返回值,而在这里 fork 却可以返回两个,关于 fork 返回值存在两个,我们之后在探讨,现在先验证 fork 是否会返回两个值,如下:

        如上所示,我们写出的了一个有关 fork 的代码,使用 id 来接收的 fork 的返回值,当 id = -1 的时候,直接结束进程,当 id = 0 的时候,执行子进程的代码,当 id 不等于 0 的时候,执行原进程的代码,从运行的结果我们可以发现,确实运行了两个进程,并且确实 fork 返回给子进程的 id = 0,返回给原进程的 id 为子进程 pid。其实在 fork 之后的代码都是父子进程之间共享的代码,然后我们使用判断将其划分,让其执行不同的代码。但是,为什么对于同一个 id,它为什么会有两个值呢

        首先先探讨是如何返回两个值的,对于 fork 而言,其既是一个接口,也是一个函数,一个由操作系统提供的函数,这个函数的返回值就是一个 pid_t 类型的值,也就是 id。我们之前也提到,fork 函数之后的数据,父子进程的代码和数据都是共享的,其实准确来说,不是在 fork 函数后,而是在 fork 函数之中就已经共享了,所以关于最后一句的返回值代码来说,就确实会分别被父子进程给分别执行一次。以上仅仅只是探讨了为什么会返回两个值,并未解决为什么 id 的值会存在两种情况,如下:

        首先对于进程与进程之间,他们之间要相互独立,互不影响,就好比结束这个进程不会影响到另一个进程一样,在父子进程之间同样如此,结束了父进程,子进程也可以继续运行,结束了子进程,父进程也不会受影响。这样产生的原因是,创建一个子进程其实就是在操作系统中产生一给内核 task_struct ,他们之间也仅仅只是 next 指针相连接的关系,和 pid ppid 之间的关系,只是称呼上叫做父子进程,那么对于子进程就一定存在自己独立的数据,这是在生成子进程写时拷贝的结果,则对于 id 存在两个值,和写时拷贝和虚拟地址都有关(关于写时拷贝和虚拟地址两个概念将会在后面的文章给出详细的解释)

        以上便是关于如何创建子进程的知识,以下给出了一个创建多个子进程的代码,如下:

2.4 proc 查看进程

        以上讲解的为进程是如何创建的,如何创建子进程。那么关于创建出的进程的信息数据是放到哪的呢,我们可以在目录 /proc 下查找到,如下:

        如上所示,我们可以在 /proc 目录中通过进程的 pid 查找的对应的进程目录,在当我们进入到目录的时候,我们就可以在这里面看到有关当前进程的信息和代码,如下:

        由上图片可以发现,在名为 exe 的一个可执行文件,其实是一个链接文件,链接的地址为,进程对应自己的可执行文件的程序。所以,进程的 pcb 中会记录下自己对应的可执行程序的路径。还有一个 cwd 链接文件,也进程当前路径,所以每个进程在启动的时候,会记录当前在哪个路径下启动,这样的好处有,当我们在进程中创建了一个文件(比如使用 fopen 创建一个文件),只要不指明路径,就会默认在当前进程所处路径中创建。

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

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

相关文章

Android Widget开发代码示例详细说明

因为AppWidgetProvider扩展自BroadcastReceiver, 所以你不能保证回调函数完成调用后,AppWidgetProvider还在继续运行。 a. AppWidgetProvider 的实现 /*** Copyright(C):教育电子有限公司 * Project Name: NineSync* Filename: SynWidgetProvider.java * Author(S…

界面组件DevExpress Blazor UI v23.2 - 网格、工具栏功能全新升级

DevExpress Blazor UI组件使用了C#为Blazor Server和Blazor WebAssembly创建高影响力的用户体验,这个UI自建库提供了一套全面的原生Blazor UI组件(包括Pivot Grid、调度程序、图表、数据编辑器和报表等)。 DevExpress Blazor控件目前已经升级…

数字文旅重塑旅游发展新生态:以数字化转型为契机,推动旅游产业的创新发展,提升旅游服务的智能化、网络化和个性化水平

目录 一、引言 二、数字化转型推动旅游产业创新发展 1、数字化转型提升旅游产业效率 2、数字化转型拓展旅游产业边界 3、数字化转型促进旅游产业可持续发展 三、提升旅游服务智能化、网络化和个性化水平 1、智能化提升旅游服务体验 2、网络化拓宽旅游服务渠道 3、个性…

爬虫的实战应用之短信炸弹playwright现代网页测试工具

不讲废话,先上原理: 短信炸弹,也就是说持续对一个手机进行发送短信,实现的方式就是,利用某些网站的登录 ,注册的时候,发送短信验证码来实现。 如下图,其中有一个id为phone的输入框&a…

配置nodejs的俩小脚本

介绍:共两个脚本。 脚本1,用来配置环境变量,生成环境变量所需的配置信息,然后自己添加到系统环境变量里去 特别注意:该脚本需要放到nodejs目录下面,如果不是,则无法生成环境变量配置文本内容 另…

Java代码审计-flink-streaming-platform-web

前言 项目地址:GitHub - zhp8341/flink-streaming-platform-web: 基于flink的实时流计算web平台 flink-streaming-platform-web是一个将flink封装的一个可视化的、轻量级的flink web客户端系统,用户只需在web 界面进行sql配置就能完成流计算任务。 项目…

【Elasticsearch<一>✈️✈️】简单安装使用以及各种踩坑

目录 🍸前言 🍻一、软件安装(Windows版) 1.1、Elasticsearch 下载 2.1 安装浏览器插件 3.1、安装可视化工具 Kibana 4.1、集成 IK 分词器 🍺二、安装问题 🍹三、测试 IK 分词器 ​🍷 四、章…

Golang | Leetcode Golang题解之第55题跳跃游戏

题目&#xff1a; 题解&#xff1a; // 贪心算法 func canJump(nums []int) bool {cover : 0n : len(nums)-1for i : 0; i < cover; i { // 每次与覆盖值比较cover max(inums[i], cover) //每走一步都将 cover 更新为最大值if cover > n {return true}}return false } …

如何买到“30元以下”的免备案服务器?

对于预算有限的个人和小型企业来说&#xff0c;30 元以下免备案服务器的价格非常亲民。用户可以以极低的成本获得所需的服务器资源&#xff0c;这对创业者、个人开发者、学生和站长来说简直不要太划算&#xff0c;毕竟配置可以升级真不够后面再付费升级也行。 何为“免备案”&…

Android双向认证配置过程

1&#xff08;可以绕过&#xff09;准备过程 为了让这个教程可以一直复用&#xff0c;打算直接写一个双向认证的APP作为素材。 工具&#xff1a; ●protecle&#xff08;签名文件转换&#xff09; ●keytool&#xff08;java自己就有&#xff09; ●openssl&#xff08;apache里…

NLP transformers - 文本分类

Text classification 文章目录 Text classification加载 IMDb 数据集Preprocess 预处理EvaluateTrainInference 本文翻译自&#xff1a;Text classification https://huggingface.co/docs/transformers/tasks/sequence_classification notebook : https://colab.research.googl…

FPGA 以太网概念简单学习

1 MAC和PHY 从硬件的角度来说&#xff0c;以太网接口电路主要由 MAC &#xff08; Media Access Control &#xff09;控制器和物理层接口 PHY&#xff08;Physical Layer &#xff0c; PHY &#xff09;两大部分构成。 MAC 指媒体访问控制子层协议&#xff0c;它和 PHY 接…

创建获利段

事务代码&#xff1a;KE21N BAPI&#xff1a;BAPI_COPAACTUALS_POSTCOSTDATA 前台操作&#xff1a; 表是业务配置的 配置路径&#xff1a; 代码&#xff1a;BAPI不返回生成的凭证号和获利段&#xff0c;需要通过增强或者读表获取 ls_copa_data-record_id 000001.ls_co…

Agent AI智能体在未来,一定与你我密不可分

随着Agent AI智能体的逐渐成熟&#xff0c;人工智能应用的不断深入与拓展&#xff0c;相信在不久的将来&#xff0c;他与你我的生活一定是密不可分的。 目录 ​编辑 1 Agent AI智能体是什么&#xff1f; 2 Agent AI在语言处理方面的能力 2.1 情感分析示例 2.2 文本分类任…

Spring - 5 ( 8000 字 Spring 入门级教程 )

一&#xff1a;Spring IoC&DI 1.1 方法注解 Bean 类注解是添加到某个类上的&#xff0c; 但是存在两个问题: 使用外部包里的类, 没办法添加类注解⼀个类, 需要多个对象, ⽐如多个数据源 这种场景, 我们就需要使用方法注解 Bean 我们先来看方法注解如何使用: public c…

Unity 踩坑记录 Rigidbody 刚体重力失效

playerSetting > physics > Gravity > 设置 Y 的值为负数

前端canvas项目实战——在线图文编辑器(九):逻辑画布

目录 前言一、 效果展示二、 实现步骤1. 调整布局&#xff0c;最大化利用屏幕空间2. 添加逻辑画布3. 添加遮罩4. 居中显示逻辑画布5. 一个容易被忽视的bug点 三、Show u the code后记 前言 上一篇博文中&#xff0c;我们实现了一组通用的功能按钮&#xff1a;复制、删除、锁定…

FreeRTOS之列表

1.FreeRTOS的列表和列表项十分重要。列表类相当于链表&#xff0c;列表项则相当于链表中的节点。列表项的地址是非连续的&#xff0c;列表项的数量可随时修改。在OS中的任务状态和数量会发生改变&#xff0c;因此使用列表可以很好的满足需求。 列表和列表项的相关定义与操作函…

电商独立站||跨境电商独立站网站搭建|功能系统搭建||API接口接入

搭建多语言跨境电商独立站系统 前台主要功能模块 短信接口 第三方登陆 支付方式 会员中心 代购订单列表 - new 会员签到 -1000(1) new 支付密码 ---1000 国内流程 -----5000 new 订单运单多退少补 -1000 未付款运单取消功能 - 修改运单运输方式 -----1000 年费会员 -----3000 …

大型零售企业,适合什么样的企业邮箱大文件解决方案?

大型零售企业通常指的是在全球或特定地区内具有显著市场影响力和知名度的零售商。这些企业不仅在零售业务收入上达到了惊人的规模&#xff0c;而且在全球范围内拥有广泛的销售网络和实体店铺。它们在快速变化的零售行业中持续创新&#xff0c;通过实体店、电商平台等多种渠道吸…