[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)

目录

0.前言

1.什么是进程(初步理解)

2.什么是进程(高深理解)

2.1什么是进程控制块PCB

2.2进程与程序的对比

2.3进程控制块PCB的作用

2.4 PCB内部属性信息构成

2.4.1 struct task_struct内容总览

2.4.2进程控制块标识符PID

 2.4.3进程控制块的状态

2.4.4进程的其他属性数据

2.4.5进程的上下文数据*

2.5查看进程的方式

2.5.1 ps axj指令

2.5.2 proc目录


0.前言

practice7 · onlookerzy123456qwq/Linuxtwo - 码云 - 开源中国 (gitee.com)icon-default.png?t=M85Bhttps://gitee.com/onlookerzy123456qwq/linuxtwo/tree/master/practice7

本文代码已上传至gitee码云,需要的同学可以自取哦~

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第1张图片(21条消息) [入门篇]初识操作系统OS(这篇博客将帮你打开操作系统OS大门的第一步 超超超超超详细)_yuyulovespicy的博客-CSDN博客https://blog.csdn.net/qq_63992711/article/details/127275042?spm=1001.2014.3001.5502

上篇博客中我们知道操作系统OS管理系统中的软硬件资源,从而来对上提供服务,而今天我们要讨论的进程,就是操作系统所管理的四大类软件资源之一。

1.什么是进程(初步理解)

进程(process),书本给出简单的定义就是 加载到内存的程序,就叫做进程。

这也确实是进程在内存中的实体,但是如果站在操作系统的角度,这样定义进程实际上是不完整的,用网络术语来说就是你看进程的格局小了

我们先初步理解一下进程是什么,进程就是加载到内存当中的程序,说白了就是在内存中跑起来的程序,我们先直观感受一下进程:

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第2张图片

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第3张图片

 如图我们在内存中执行一个程序./myproc(其实就是把该程序加载到内存当中执行起来使之成为一个进程),就可以在内存找到myproc这个进程

我们常用的查看现在内存中的进程的指令是ps axj并配合grep行过滤指令,找到该进程的信息,ps axj | head -1可以对查看进程都信息加上标题,方便我们查看,所以我们通常使用ps axj | head -1 && ps axj | grep proc_name来查看进程。

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第4张图片

 再拉近到我们生活当中,我们在电脑上打开一个软件打开一个游戏,这些过程其实就是在执行一个程序,也其实就是将该程序加载到内存中,其实就是在创建一个一个的进程

从今天开始,我们不要称电脑中的一个个运行起来的软件为程序了,而应该叫它进程

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第5张图片

2.什么是进程(高深理解)

刚才我们简单的认识进程是加载到内存中的程序站在系统的角度看,这其实是非常浅显的,进程不仅仅只是加载到内存中的程序,其实还应该加上进程的PCB(进程控制块)

2.1什么是进程控制块PCB

我们在上一篇博客中讲过,进程是一类软件资源,操作系统就要对系统中的多个进程进行管理,而操作系统管理进程的方式就是管理进程的数据,就要对进程先描述在组织,将每一个进程的属性信息统一在一个struct结构体中,然后把一个个struct结构体组织起来形成数据结构,操作系统对进程的管理就变成了对这个数据结构的增删查改,这也是为什么需要有PCB进程控制块的存在

事实上,这个struct,对每一个进程的属性信息集合就是进程控制块(PCB),在Linux中这个进程控制块,这个存储进程属性的结构体的名字struct task_struct !!!

PS:进程是内存中运行起来的程序,每一个进程都有相应的属性信息集合,这些信息统一在一个结构体中,不同操作系统中这种结构体的名字都不同,不过他们都统称为进程控制块(PCB),而在Linux操作系统中这个结构体/这个进程控制块 的名字叫task_struct。在其他的操作系统中进程控制块(PCB)的名字可能叫另一个,但是他们的本质都是进程的属性信息集合

每一个进程都有一个配套的PCB(进程控制块),在一个进程被创建的时候,此时操作系统会针对该进程创建出一个struct task_struct进程控制块

总之, 进程==运行的程序 + 该进程的进程控制块

2.2进程与程序的对比

首先我们对比一下程序和进程,

程序 = 存储在磁盘上的文件

进程 = 加载到内存(运行起来) 的程序 + 进程的PCB

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第6张图片

程序就是一个存储在磁盘上的文件,而当程序加载到内存当中,就变成了内存中的一个进程,此时OS会自动为之创建一个PCB存储该进程属性信息,这个创建的PCB加载到内存程序本身,两者一起才是完整的进程!

2.3进程控制块PCB的作用

首先我们看一下内存中的进程以及PCB的创建:

内存中有很多进程,OS都会对每一个进程创建一个PCB进程控制块(即struct进程属性数据集合) , 然后将一个一个的struct进程控制块数据结构的形式组织在一起(如下图)

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第7张图片

 操作系统主要通过操控数据结构,即PCB完成对进程的相应操作,所以此时OS操作进程不再会过度的依赖操作进程实体,而是去调度PCB来完成对进程的操作

下面我们举个OS调度进程执行的例子来说明:

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第8张图片

进程的运行实际上就是在被CPU运算的过程,进程要运行下去就要享用CPU资源,而内存当中我们载入了许多的软件程序(即有很多进程),

 OS此时通过调度进程控制块形成运行队列,来完成进程对CPU运算执行功能的排队,这个过程中OS并不直接操作进程的代码+数据实体,而是一直在操控PCB

有了进程控制块,所有的进程管理任务与进程对应的程序将毫无关系!而与进程对应的OS内

核创建的OS内核创建的该进程的PCB强相关!

总结一下,PCB进程控制块其实就是进程代码数据实体的属性数据集合结构体struct,OS通过对PCB的管理来管理进程实体,对进程的操作转变成了主要对进程控制块的操作PCB在一定程度上就代表了进程!!!

2.4 PCB内部属性信息构成

说完了进程控制块的作用,那接下来我们就深入到PCB内部,了解PCB内部的关于进程的属性信息到底有哪些:

2.4.1 struct task_struct内容总览

struct task_struct内容分类:(PCB内部进程属性信息组成模块)

标识符 描述本进程唯一的标识符,用来区别其他进程。
状态 包括任务状态,退出码,,退出信号等。
优先级 相对于其他进程的优先级。
程序计数器 程序中即将被执行的下一条指令的地址。
内存指针 包括程序代码和进程相关数据的指针,以及和其他进程共享的内存块的指针。
上下文数据 进程执行时处理器中寄存器中的数据。
I/O状态信息 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
记账信息 可能包括处理器时间总和,使用的时钟总和,时间限制,记账号等。
其他信息 其他有关进程的信息。

2.4.2进程控制块标识符PID

标识符,在Linux操作系统的进程控制块task_Struct中,我们称之为PID,这是标识进程唯一性的符号,可以用来区别其他进程

 PID进程标识符的作用可以类比学校,在公司中,每一个学生都有一个独一无二的学号每一个员工都有一个独一无二的工号,来区别每个学生,每个员工学号工号也成为你在学校在公司中的唯一标识

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第9张图片

 那我们如何获得每一个进程的唯一标识符呢?

一是可以通过ps axj指令,来查看系统中正在运行的进程,从而找到进程的PID,如何让进程(运行起来的程序)自己主动打印自己的PID呢?我们可以使用getpid系统调用接口:

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第10张图片

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第11张图片

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第12张图片

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第13张图片

进程不仅能通过getpid()获得自己运行时的PID标识号,还可以通过getppid()获得自己父进程的PID标识号,没错,每个进程都是有父进程的。这个我们在之前讲shell的博客中举了个实习生的例子,即有些危险性的程序进程并不由媒婆bash亲自去执行,而是交由实习生即bash创建出的子进程去执行 , bash就是父进程。所以进程的创建实际上都是在父进程的基础上创建出来的创建出来的进程叫做子进程。如下图演示:

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第14张图片

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第15张图片

 2.4.3进程控制块的状态

task_struct中的状态属性数据,存储的主要是进程的任务状态,退出码,退出信号

首先讲一下退出码

我们写的程序末尾总会有一个return 0;语句用来结束这个函数,而事实上,这个return的值就是该进程的退出码,我们可以通过echo $?指令获取上一个进程的退出码。如下图演示:

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第16张图片

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第17张图片

进程return的退出码首先会交给操作系统,因为操作系统是进程PCB的管理者,最后再由操作系统交给它的父进程。而后面我们也会演示,父进程可以通过进程等待wait的方式来获取到子进程的退出码

下面讲 进程的任务状态:

并不是每个进程都在同时运行的,进程也不会一直存在。进程有如运行状态,等待状态,死亡状态,挂起状态,休眠状态......

类比我们作为学生,有学习状态,睡觉状态,吃饭状态,老师也不可能让我在吃饭状态的时候去学习,老师也不可能让我在睡觉状态时去学习。

具体进程各个状态的展现我们会在后续的博客中进行实践演示。

2.4.4进程的其他属性数据

优先级:

进程的运行依靠的是CPU的运算,而CPU只有一个(单核情况下),而各个进程都要运行使用CPU,之前在讲PCB的作用时,我们知道OS操作系统是调度PCB,将PCB组织在运行队列run_queue中依次接受CPU对进程的运行。这个排队的过程就是优先级的体现,优先级就是说明谁先谁后使用CPU资源,即在运行队列run_queue的先后排队位置

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第18张图片

打个比方:在食堂打饭,我们学生都要排队轮流打,而我们都要打饭,现在有个伟大的学校领导也来食堂打饭,他的打饭排队优先级是很高的,就可以直接插在打饭队列的前方进行优先的打到饭,即优先级高的PCB进程可以在运行队列的前部,优先享用到CPU资源。而一些优先级低的进程则会被无限制的插队,比如我这种很老实的低年级卑微的学生,我排队打饭的优先级是很低的要享用到CPU资源总是要先让优先级高的进程执行

程序计数器:是程序中即将被执行的下一条指令的地址。

我们进程作为在内存中运行的程序,并不是被CPU一次性执行完的一个进程的执行要被CPU分段执行多次,所以记录进程执行到代码的哪一行对一个进程就显得尤为重要。PCB中程序计数器的作用就是记录该进程现在执行到哪一行了。

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第19张图片

CPU当中有一个寄存器,我们将其叫做PC指针,指向内存中的一块地方指向的就是CPU要执行的指令CPU就从内部的PC指针这里知道它要执行的下一条指令在内存的某某地方。再从CPU的角度理解,现在一个进程的PCB来了,需要要被CPU去运行,那CPU如何知道去哪里执行呢?也就是在问PC指针里面的地址应该如何知道你这个进程执行到了哪一行呢(实际上需要的是该行的地址)?这时候靠的就是PCB中的程序计数器PCB进程程序计数器里的存的地址放入到CPU的pc指针,CPU就知道下一个要执行的指令在内存的哪里了。

内存指针

内存指针是进程控制块中的指针指针指向程序代码和进程相关数据,还有和其他进程共享的内存块。所以我们可以说PCB进程控制块可以在一定程度上代替进程实体本身,OS内核调度使用的也都是PCB这个数据结构,而不是进程本身。

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第20张图片

I/O状态信息:

所谓的I/O其实就是内存和输入设备(input),内存和输出设备(output)的交互

先需要明确一件事,所谓的文件操作,其实并不是你在操作文件,换句话说,你在进程里调用open,write,read读写打开一个硬盘中的文件,而是这个过程是进程在打开文件,是进程在读取文件,是进程在写入文件,是进程在和文件进行交互,这个以后具体会在以后的博客讲述进程和文件的关系以及文件的本质的时候说到。

进程和文件关系紧密,由进程操作文件,文件都存储在磁盘中,进程读取文件前,必须先把文件载入到内存中,而进程要对文件进行写入,就需要先把内容写入到内存,最后输出到磁盘中,此时都会进行磁盘IO。所以进程的IO信息需要被记录

进程的I/O状态信息,包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表

记账信息:

记账信息就相当于一个不可或缺的日志。我们先说明一件事:

在操作系统中,有一个调度模块,较为均衡的调度每个进程让这个进程较为均衡的获得CPU资源,进程才能被执行(让进程较为公平的得到执行),记账信息就是记录这个进程历史上已经享用过的软硬件资源的集合,这就叫做记账信息。比如一个进程已经被CPU调度了100ms了,我这个进程还只被CPU执行了0.01ms,这些都是记账信息,不过这样100:0.01的被CPU执行时间的悬殊比例,是极其不公平的,这个算法是有问题的,如果我们对进程被CPU的执行时间进行记账,就可以根据记账信息适当提高或降低该进程的优先级,从而让这个还没有怎么被CPU执行的进程能够在运行队列的前面快速使用到CPU资源,让进程较为均衡公平的执行

最后我们着重讨论一下PCB中进程的上下文数据

2.4.5进程的上下文数据*

要介绍进程的上下文数据,就要首先介绍进程在计算机中的运行原理

操作系统主要通过操作进程控制块PCB来操纵进程,而进程要被执行就要被CPU计算运行操作系统调度进程的PCB将PCB维护成一个运行队列让这些进程处于可执行的状态,进程排队给CPU进行调度执行

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第21张图片

事实上CPU对进程的执行并不是一蹴而就的,即一个进程不会一直占用CPU资源,直到这个进程执行完才会结束对CPU资源的占用,才能再让下一个进程去执行,这其实是十分不合理的。举个例子,我们在电脑上进行微信聊天,这是一个进程,但是现在CPU被一个下载软件的进程占用着,如果进程必须一直占用CPU资源直至结束才会离开,那除非这个软件被下载完毕(下载进程结束),不然你就无法使用微信聊天发送消息(微信进程无法享用到被占用的CPU资源),万一现在有一个特别紧急的事情,那就糟糕透了

但是,我们的电脑也只有一个CPU,那为什么我们作为用户可以一边进行微信聊天,一边在CSDN上写博客,一边在网易云上听音乐呢?事实上我们的CPU也是一次只能服务一个进程的运行呀?!这其实是通过CPU对每个进程运行的快速切换实现的微信进程在CPU上运行几毫秒然后从运行队列下去,然后CSDN博客进程在CPU上运行几毫秒再从运行队列下去,网易云音乐进程再.....几毫米用户是感受不出来的,这样通过进程间的快速切换运行,就可以给用户营造一个所有进程应用都好像在同时运行的假象,这也给我们用户极好的体验

所以实际上一个进程是要被调度上千次被CPU计算运行上千次才能最终被执行完毕进程并不是一步到位就能被跑完的!!!

我们此时也可以引入时间片的概念进程快速切换,被CPU执行的很短的这个时间其实就是时间片,当一个进程在CPU上运行的时间片到了这个进程PCB就会回到运行队列run_queue的尾部重新进行排队。然后这些进程来回循环式的执行一个时间片然后到尾部让下一个排到队的进程去执行,如果在某个时间片内一个进程执行完毕了,就可以从运行队列中下来了。比如我们的一个进程需要大概10s才能执行完毕,而CPU的时间片是1ms,那就需要1000+次被CPU调度运行才能运行完这个进程。

这才是进程在计算机中运行的方式!!!

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第22张图片

进程要被CPU执行成百上千次,也就是说一个进程要剥离再回到CPU上百上千次,那每一次执行出来的结果和数据需不需要保存呢,当然需要保存,不然这次时间片执行计算出来的相关数据不就白费了嘛(哭死)!所以每次进程剥离CPU服务需要保存进程的核心临时数据,而这些数据是由CPU计算出而存储在CPU上的寄存器当中的,而寄存器只有一份,下一个进程从运行队列再上来运算时,会覆盖我这个进程在CPU寄存器上的临时数据,所以进程PCB需要带走这些存储在CPU寄存器中的数据轮到下一次对此进程的继续执行时,会先在CPU寄存器上恢复执行到这一步的数据,而不至于让这个进程“失忆”丧失之前已经计算出的临时数据。这些需要被进程PCB记忆带走的临时数据其实就是进程的上下文!!!等到这个进程下一次再被CPU执行的时候,就会把PCB中的上下文临时数据再恢复到CPU当中,从而达到切换之后仍然可以保留记忆继续执行的目的。

为了帮助我们理解上下文,我们举个现实中的例子:

每个大学里都有大学生入伍的名额,而你从小就有从军报国的理想,所以你就去面试,最后也是通过了面试成为了一名光荣入伍的大学生。

这时候你回到宿舍,说:"兄弟们,我要去当兵了,一年后再见!”,然后你马上收拾行囊去往部队去了。一年之后你回来,发现出事了,你居然发现自己挂了十几门科目,各种实验,报告,论文都没有交上,你马上就要被劝退了!!! 这个过程中主要的问题在于你在入伍时没有通知学校,所以学校不知道你应征入伍了,仍然按照你正常在学校上课去办理你的学业。

假设你面试入伍成功之后,你去学校教务处报备,说你需要离开学校一年参军,学校此时就会中断你的学业进程,保留你现在的学业与学籍,等一年后知道你回来了再继续按现在的保留的数据继续完成你的学业。

这个行为其实就是进程PCB剥离CPU时带走临时数据的过程,也叫做上下文数据的保存。

故事继续,经过一年在部队的历练,你终于可以光荣退伍回来上课了!这时候,你回到了宿舍,踢开屋门,大喊一声:"兄弟们,我的军旅生涯告一段落了!来和兄弟们一起学习了!”,然后你就和兄弟们一起上了一个学期的课,交了一个学期的作业,各种运动会,志愿活动都去参加,忙活了一个学期,到期末考试的时候,你居然发现没有自己的考场,考试名单上也根本没有你!这很好解释,因为你回来的时候没有和学校教务处打招呼,所以结果就白白忙乎了一个学期。

正确的做法应该是在一年的部队生涯结束之后,你回到学校的第一件事是去教务处,跟教务处说你已经退伍返校,可以继续之前保留学籍学业的学习,学校根据一年前保存过的你的学籍学业信息恢复你的学业学籍,让你继续学习,这样你就可以无缝衔接,继续开始你剩下的大学生涯了。

这个行为其实就是进程PCB再次来到CPU计算时恢复临时数据的过程,也叫做上下文数据的恢复。

上下文数据的保存和恢复,是保障进程快速切换CPU时间片多次运行进程机制的重要保障,没有上下文的保存,就不能让进程还没执行完就被切换,不能切换也就意味着不能给用户多个进程都在同时运行的“体验”以及进程快速的响应时间

2.5查看进程的方式

2.5.1 ps axj指令

 我们常用查看现在内存中的进程的指令是ps axj并配合grep行过滤指令,找到该进程的信息,ps axj | head -1可以对查看进程的信息加上标题提示,方便我们查看,所以我们通常使用ps axj | head -1 && ps axj | grep proc_name来查看进程。

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第23张图片

2.5.2 proc目录

Linux内核提供了一个proc目录,我们 ls /proc/即可查看这个目录里的文件内容,而/proc里面存储的都是当前系统中正在运行的进程,存储的方式是以进程自身的PID编号作为一个文件夹,文件夹中存储着每个进程的具体信息

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第24张图片

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第25张图片

[入门篇]手把手带你理解进程在计算机中到底是什么!(Linux系统新手必看哦)_第26张图片

其中我们可以观察到一个cwd文件,这个是进程的当前工作路径信息,也就是./myproc这个myproc进程的运行路径。如图就是我在/home/zy/103/practice7/中执行的myproc进程,在cwd中可以看到这一信息

其实这样变相的说明了,你在程序中打开fopen文件,如果不写路径的话,这个进程就默认在程序的工作路径cwd下下打开该文件,如果以“w”写的方式打开文件,我们知道如果该文件不存在会自动在当前路径创建一个该文件,而创建文件的当前路径其实就是这个cwd当前工作路径

总之,/proc/pid_num也是一个查看具体进程的方式。

你可能感兴趣的:(Linux操作系统-系统编程,服务器,运维,linux,学习,vim)