• 详细讲解 —— 进程(Java EE初阶)


    一、什么是操作系统

    操作系统(Operating System)是一组做计算机资源管理的软件的统称。目前常见的操作系统有:
    Windows系列、Unix系列、Linux系列、OSX系列、Android系列、iOS系列、鸿蒙、mac系列、openwtr系列等。

    总结来说,操作系统就是一个“软件”,是计算机中最重要,也是最复杂的软件之一。

    操作系统主要做了两件事情:

    1. 管理好各种硬件设备。
    2. 要给各种软件提供稳定的运行环境。

    操作系统是把硬件和软件连接起来的。

    操作系统的定位
    计算机系统的分层视图
    操作系统所提供的功能是非常复杂的,其中比较重要的就是进程(软件资源的管理),下面来介绍操作系统中进程。

    二、什么是进程

    进程是操作系统对一个正在运行的程序的一种抽象,换言之,可以把进程看做程序的一次运行过程;同时,在操作系统内部,进程又是操作系统进行资源分配的基本单位。

    进程(process)还有另外一个名字 任务(task)

    什么是正在运行的程序
    在我们下载软件的过程中,要下载一些文件,其中我们会发现一个文件的后缀名为.exe,这个文件为可执行文件。

    如果我们不双击这个可执行文件,那么这个文件会在硬盘中,不会对系统有什么影响。
    如果我们执行这个可执行文件,操作系统就会把这个可执行文件就会从硬盘加载到内存中,并且让CPU开始执行可执行文件内部的一些指令,这样程序就开始进行一些具体的工作了。

    我们把这些运行起来的可执行文件称为“进程”。
    进程
    上图就是在我电脑上正在运行的进程(可以从任务资源管理器中查看,当前电脑的进程)。

    三、进程控制块(PCB)

    操作系统是如何管理进程的

    1. 先描述一个进程(明确出一个进程上面的一些相关的属性)。
      操作系统主要是由C/C++来实现的,而此处描述是C语言中“结构体”所实现的,操作系统中描述进程的这个结构体,称为“PCB”(process control block)。
    2. 组织若干个进程(使用一些数据结构,把很多的描述进程的信息给放到一起,方便进行增删改查)。
      典型的实现是用双向链表来把每个进程的PCB给串起来,这里典型的实现是指Linux系统,操作系统的种类是有很多的,每一种操作系统实现可能不尽相同,具体的还是要看操作系统的原码。

    创建进程 — 先创建出PCB,再把PCB放到双向链表中。
    销毁进程 — 现在双向链表中找到PCB,再删除相应的PCB。
    查看任务管理器 — 遍历双向链表并打印。

    PCB中的基础属性

    1. pid(进程id)进程的身份标识。
      每一个进程,都有一个独一无二的编号,这个编号就是进程的pid。
    2. 内存指针。
      指明了这个进程要执行的代码、指令、以及所需要的数据在内存的那一块空间中。
      在执行可执行文件中,CPU就要通过这个内存指针来找到进程在内存的那一快空间中。
    3. 文件描述符。
      程序运行的过程中,经常要和文件打交道(文件在硬盘上,不在内存上)。
      当进程每打开一个文件,就在文件描述符表中增加一个,文件描述符表可以看做是由数组来组成的,在打开进程时,系统会自动打开三个文件,分别是:标准输入(System.in)、标准输出(System.out)、标准错误(System.err)。
      其中文件描述符表中的下标为文件描述符。

    上面的属性是一些基础的属性,下面的一组属性,主要是为了实现进程调度。

    PCB中为了实现进程调度的属性

    进程调度(是理解进程管理的重要话题)
    现在的操作系统都是可以执行多任务的操作系统(一个系统同时执行了很多的任务)。像Linux系统,Windows系统等等。
    在同一时刻很多的程序都在运行,像qq,画图板,qq音乐,idea等等,操作系统同时管理这些程序,这个就是进程调度。

    我们系统上的进程数量,有几十个,上百个,但是我们的CPU核数就那么几个(6核或8核),那个这六个核心怎么调用这么多的进程。这就需要CPU进行并发执行。

    并行和并发
    并行:微观上,两个CPU核心,同时执行两个任务的代码。
    并发:微观上,CPU一小段时间执行任务1,一小段时间执行任务2,一小段时间执行任务3…,只要执行的足够快,在宏观上就可以看成是同时运行。

    CPU执行的到低有多快呢?
    计算机参数
    上面图片是我电脑上的参数,其中处理器是3.00GHz。
    其中1G = 1024M, 1M = 1024K, 1K = 1024。
    所以3GHz用计算器来算差不多就是34多亿次,这个是1秒钟可以执行指令的次数。所以就算计算机同时执行几个进程,我们在宏观上也是感受不到的。

    正是因为我们在宏观上区分不了,并发和并行,所以我们一般用并发来代指 并行 + 并发。
    只有我们在讨论操作系统调度这个话题的时候才作区分。

    属性

    1. 状态。
      这个状态告诉进程接下来该怎样调度。
      有两种状态:一种是就绪状态,随时可以去CPU上执行;另一种是堵塞状态,暂时不可以去CPU上执行。
      Linux中的进程状态还有许多其他的。
    2. 优先级。
      同时执行多个进程。操作系统给哪一个进程分配的时间多,给哪一个进程分配的时间少;以及先执行哪个进程,后执行哪个进程。
    3. 记账信息。
      统计每一个进程执行了多久,分别执行了那些指令,等待了多久,为以后的进程调度提供依据。
    4. 上下文。
      表示上次进程调度出CPU的状态信息,为下次调度进程进CPU后,继续往后执行。
      就相当于我们进游戏的存档和读档,在我们退出程序之前,要存档,下次进入游戏系统自动读档,从我们上次退出时状态继续下去。

    四、进程的独立性(虚拟地址空间)

    在现在的操作系统上同时运行着多个进程,如果某一个进程出现了bug,进程崩溃了,但是不会影响其他的进程,能够做到这一点就是“进程的独立性”来保证的,而进程的独立性依仗着“虚拟地址空间”。

    如果一个进程出现了bug,崩溃了,在早期的操作系统中,其他进程也会崩溃,这是因为早期的操作系统中的进程是访问同一个内存地址空间的。一个进程崩溃,其他的跟着崩溃。

    为了解决早期的操作系统出现的问题,就出现了虚拟地址空间。

    每一个进程在内存中都有一个不同的地址空间。其中有的进程分配的空间大,有的进程分配的空间小。具体的大小要根据进程的大小,然后由操作系统来分配。

    五、进程间的通信

    进程之间通过虚拟地址空间,已经各自之间隔开了。
    但是有的时候进程之间是需要进行交互的。

    进程间,进行通讯是通过公共地址空间来实现的。这个公共地址空间,不在进程A中也不在进程B中。
    进程A把信息存放到公共空间中,进程B再从公共空间中把信息读走。这样就实现了两个独立进程之间的交互。

    在操作系统中,提供的“公共空间”有很多种,并且各有特点。
    有的存储速度快,有的存储速度慢,有的存储空间大,有的存储空间小。操作系统中提供了多种这样的进程间通信的机制。

    现在最主要使用的进程间通信方式,有两种:

    1. 文件操作
    2. 网络操作

    在后面的文章中会详细讲解。这里想大致了解一下。

  • 相关阅读:
    Redis IO多路复用理解
    python使用技巧(三十):python保存本地npy与C++调用npy
    AI:70-基于机器学习的水质检预测
    【JAVA】LinkedList与链表(Part1)
    基于javaweb的顶岗实习管理系统(jsp+servlet)
    软件设计模式学习笔记(七)
    Linux 服务器(Ubuntu) 安装 golang记录
    Qt扫盲-QListView理论总结
    3、Tomcat类加载机制
    【深度学习】【Opencv】【GPU】python/C++调用onnx模型【基础】
  • 原文地址:https://blog.csdn.net/IT_Infector/article/details/125445951