进程是计算机科学中非常重要的概念,它是操作系统中的一个基本单位,负责执行程序并管理资源。在JavaEE开发中,进程的概念同样非常重要,因为JavaEE应用程序通常是多线程的,每个线程都是一个进程的一部分。在本文中,我们将深入探讨进程的概念、特性和在JavaEE开发中的应用。

一、什么是操作系统?

首先我们想要了解什么是进程,我们就要先简单了解什么下是操作系统,耳熟能详,pc端主流的操作系统有微软的Windows、苹果的macOS、Linux,还有移动端的 Android、苹果的iOS这些,都是十分主流的操作系统。再来看一张图片:

进程解析(JavaEE初阶)_文件描述符

如上图,这些操作系统干的事情都如出一辙,

第一件事情是防止硬件被时空的应用程序滥用。

第二间事情是作为软件试用硬件的工具来控制硬件,这句话可能有点难以理解,我是这么理解的:因为硬件的结构特别复杂,而不同的硬件之间又大相径庭,所以程序猿们就设计出了操作系统这一个东西,提供一个接口给软件使用,然后软件就不需要考虑这是哪一种类型的硬件了,直接使用这个接口,操作系统帮助你操控硬件。


二、什么是进程?

提到进程,最先想到的是买快递,比如说我昨天下的单,然后今天我看看快递到哪儿个位置了,这里面到哪个位置是不是就是快递的进程呀?但是操作系统中的进程和这个进程可不一样,我们程序猿眼中的进程就是跑起来的程序,那什么又是程序呢?如下图:

进程解析(JavaEE初阶)_文件描述符_02

这些 .exe 文件就是程序啦,可是只有双击才能开始运行,开始运行之后,才是我们所说的进程,如下图:

进程解析(JavaEE初阶)_文件描述符_03

这些东西就是进程啦 ,所以可以得出一个结论-->进程是操作系统对一个正在运行的程序的一种抽象,换言之,可以把进程看做程序的一次运行过程;同时,在操作系统内部,进程又是操作系统进行资源分配的基本单位。 


三、进程的内部结构

那进程又是如何运行起来的呢?

首先举个例子:想开汽车,首先得先合适的场地吧?还得有油/电吧?当然,还得要有驾驶证、行驶证这些吧?而且行驶证的车辆类型记录必须与驾驶证的准驾记录相符······做这一系列的工作,汽车才能启动。进程也是一样,想要他运行起来,肯定要给他分配一些资源,例如内存、cpu、磁盘、网络······这一系列的东西,如下图:

进程解析(JavaEE初阶)_优先级_04

在我们的资源管理器中就会显示一部分,首先我们先说比较重要的几个资源点:PID、内存指针、文件描述符表、进程的调度信息(进程的状态、上下文、优先级、记账信息)

3.2、PID

这个顾名思义,就是进程的一个 id,每个进程的id是不一样的,如下:

进程解析(JavaEE初阶)_文件描述符_05

如上图,最右边现实的数字就是 pid 了,至于为什么 AMD Software 中有那么多 PID 呢,这是因为下面那些都是这个进程中开的线程,至于什么是线程,先别急,往下看。

3.3、内存指针

和汽车一样,如果想要开车的话,是不是需要场地呢?进程也是一样的,想要运行起来,也需要开辟一块内存给他,当我们双击 .exe 文件时,操作系统就会把这个文件加载到内存中,变成进程

3.4、文件描述符表

文件大家都学过吧?这是c语言那部分的内容,不知道大家还有没有印象呢,在c语言中,我们讲的文件,也是通过一些指令(例如fopen、fclose、w、a、r)来操控文件的,文件描述符表也是类似,通过用户对软件所下达的指令然后通过文件描述符表进行转换,转换成机器的硬件指令。

3.5、进程的调度信息(cpu 的分配)

在讲解调度信息之前,我们得先稍微了解一下操作系统的并发和并行

像我们现在的 Windows 系统,同一时刻很多进程都在运行,如微信,QQ,画图板,idea等,我们系统上的进程数量有几十个甚至上百个,但我们的 cpu 只有那么几个,那么这是怎么做到的呢?就是依靠进程调度。

并行:在微观上,两个cpu核心同时执行两个进程,宏观上也是同时执行

并发:微观上,一个 cpu 核心先执行一会进程1,再执行一会进程2,再执行一会进程3,只要切换的够快,宏观上看起来就是很多进程一起在执行。

进程的调度信息主要包括以下四种:状态、优先级、上下文、记账信息,下文详细介绍每种信息

a、进程的状态

进程的状态主要分为两种状态:就绪状态和阻塞状态

  • 就绪状态:很容易理解,时刻准备就绪!就差不多是这个意思,表示随时可以去cpu上运行的状态
  • 阻塞状态:还有一种叫法是睡眠状态,表示暂时不能运行,是处于睡着状态的

b、进程的优先级

优先级优先级,顾名思义,就是谁优先,谁落后,比如使用一台电脑,在后台挂着微信,现在想用来玩游戏了,那我肯定希望游戏性能拉满是吧,所以 cpu 这时候就优先考虑游戏这个进程,让游戏这个进程优先进行,当然,后台的微信也不能就不考虑了,如果不分配资源的话,那不就直接挂了嘛

c、进程的上下文

和我们玩游戏时的存档一样,因为我们的 cpu 都是并发进行的,是不是要记录上一次运行到哪个位置,下次要干什么,然后这次接着上次运行到的位置继续往下运行呢?进程的上下文就是记录这个东西的

d、进程的记账信息

这是记录一个软件运行了几次,还是上面那个例子,我后台一个微信,前台玩着游戏,虽然说希望游戏性能高一点,微信可以稍微晚个一两秒收到信息这是没问题的,可是如果说晚个十多二十分钟收到信息,这就不是很好了,再激进一点,这个发消息过来的人是你的女朋友,晚个十多分钟这不就直接被贴寻人启事了?记账信息这时候就有用的,需要性能高一点的软件,分配的次数就多一点,反之则少一点,但是也不能少的太离谱,然后几张信息记录这个进程执行了多少次,至少不能少于分配的这个次数,相当记账信息就是用来兜底的。

3.6、进程间的通信(内存的分配)

进程的调度主要考虑的是 cpu 的分配,但是我们的计算机不是只有 cpu 呀,那多出来的内存又该如何分配呢?这就是我们进程间通信所涉及到的问题了。

我们进程之间正常情况下是不相互影响的,但是如果一个程序有bug了呢?如下图,我来举个例子

进程解析(JavaEE初阶)_进程_06

翻斗花园里面住着五户人家,在所有人都正常情况下是没什么问题的,但是假设这时候牛爷爷身体弱,感染新冠了呢?这时候肯定就会感染给其住户了,那这时候最好的办法就是把每户人家都隔离开来,才能让受感染的人最小化,进程之间也是一样,如果我们直接就用内存指针分配内存,如果一个进程出 bug 了,例如野指针,指到另外一个程序去了,那另外一个程序不就跟着出 bug 了吗?那我们聪明的程序猿就想出了一个办法,那就是分配虚拟地址,具体的方案就是把每个进程完全的分隔开,然后每个进程都假设存储的虚拟地址号是 0x000000 - 0xffffff,这样的话,如果一个指针所指向的地址是 0xffffffffff,那就直接能判断这个指针指错了,然后进行下一步计划。

但是这么做有个坏处,那就是进程就完全隔离开了,相互影响不了一点,有时候我们又需要进程之间相互影响,还是上面翻斗花园这个例子,如果说壮壮家没有土豆了,想要借其他人的土豆吃,那总不能说不吃等着挨饿吧?所以我们可以设定一个公共区域,我们可以把菜放到公共区里面,然后再让需要的人下来拿,进程也是一样,比如一个游戏,我是用微信登录,每次输入微信账号和密码,是不是就很麻烦呢?所以我们有时候还是需要进程之间相互影响的,把微信这个进程的信息放到公共区域,游戏进程需要的话再取走。


四、总结

总结来说,进程解析是计算机操作系统中的一个重要概念,它能帮助我们更好地理解系统运行的机制,提高系统性能的同时也能更好地优化资源的利用。通过学习进程解析,我们可以更好地理解程序执行的过程,优化程序设计和调度,提高系统的效率和性能。


五、结语

在学习进程解析的过程中,我们不仅仅是在获取知识,更重要的是在培养自己的分析能力和解决问题的能力。进程解析并不仅仅是一个概念,它是我们对计算机系统运行机制的理解和把握,是我们在编程过程中优化算法和提高效率的利器。通过深入学习和实践,我们可以不断丰富自己的经验,提升自己的技能,在技术领域迅速成长。

正如林肯曾经说过的,“给我六个小时砍倒一棵树,我将花前四个小时磨刀。”这句话告诉我们,准备和学习才是成功的关键。在学习进程解析的过程中,也许会遇到困难和挫折,但只要坚持学习、勇于挑战自己,就一定能取得成功。相信自己,坚持不懈,你一定能够攀登技术之巅,成为行业的佼佼者。

每一次学习都是一个过程,每一次进步都是一个积累。在漫漫求知路上,坚持不懈,持之以恒,你的努力终将得到回报。让我们一起努力,不断突破自己的技术边界,追逐自己心中的那个闪耀的梦想。梦想的路上虽然会有坎坷和挑战,但只要我们坚持不懈、努力拼搏,终将迎来属于自己的成功和辉煌。让我们一起为梦想而努力,为未来而奋斗!加油!