计算机系统进程模型概念

℡╲_俬逩灬. 提交于 2020-01-25 16:24:01

计算机系统进程概念

以下进程概念内容均来自:https://www.bilibili.com/video/av16710919?p=13https://blog.csdn.net/qq_40421919/article/details/85224864 与《Linux网络编程(第二版)》


首先,我们需要区分程序与进程:

狭义上说:
进程与应用程序的区别在于:应用程序作为一个静态文件存储在计算机系统的硬盘等存储空间中。而进程则是处于动态条件下由操作系统维护的系统资源管理实体。

他们之间最大的不同之处在于(狭义上):

  • 进程是动态的,而程序是静态的;
  • 进程有一定的生命期,而程序时是指令的集合,本身并无"运动"的含义。没有建立进程的程序不能作为1个独立单位操作系统的认可。
  • 一个进程只能对应一个程序,一个程序可以对应多个进程。进程和程序的关系就像戏剧和剧本之间的关系。

广义上说:
进程从用户角度来看时应用程序的一个执行过程。从操作系系统核心角度来看,进程代表的是操作系统的分配的内存,CPU时间片等资源的基本单位,是为正在运行的程序提供的运行环境。



好的,在大致区别进程和程序的不同后,我们来看看进程的相关来源与其相关知识:

来源:

早期的计算机中只支持单道程序(单道程序设计),因为只有一个物理程序计数器,所以所有的程序是串行执行的,即A程序运行完成,B程序才能开始运行。计算机中的所有资源都只被一个程序所享有,包括内存。所以内存只供当前运行的程序所使用。如果程序A遇到了阻塞,则程序B一直不能运行。这样的资源分配是不合理的,同时这大大的浪费的CPU的效率。

然而随着计算机的发展,开始有了多道程序(多道程序设计),即内存中同时存放几道相互独立的程序,每个程序变成了一个独立的控制流,每个程序都有一个逻辑程序计数器。这是操作系统虚拟的一个体现,将一个物理程序计数器变换成多个逻辑程序计数器。但因为物理上只有一个(物理)程序计数器,所以那个程序真正上CPU,就把那个逻辑程序计数器推送到物理程序计数器。通过这种变换,达到了在内存中有多个程序并发运行的效果(宏观)。

进程是操作系统中最基本、重要的概念。是多道程序系统出现后,为了刻画系统内部出现的动态情况,描述系统内部各道程序的活动规律引进的一个概念,所有多道程序设计操作系统都建立在进程的基础上。

并发环境与并发程序:

并发环境:
  指的是一段时间间隔内,在物理机器上有两个,或两个以上的程序它们处于开始运行,且未结束运行的状态。也就是说,一个程序开始执行了,在还未结束时,另一个程序又开始运行了。注意,在并发情况下程序之间谁先执行,谁后执行,这是没法预测的。

并发程序:
  在并发环境中执行的程序,称为并发程序。

多道程序设计:

  • 在计算机内存中同时存放几道相互独立的程序,它们在管理程序控制之下,相互穿插的运行。多道程序设计必须有硬件基础作为保证。
  • 时钟中断即为多道程序设计模型的理论基础。 并发时,任意进程在执行期间都不希望放弃cpu。因此系统需要一种强制让进程让出cpu资源的手段。时钟中断有硬件基础作为保障,对进程而言不可抗拒。 操作系统中的中断处理函数,来负责调度程序执行。
  • 在多道程序设计模型中,多个进程轮流使用CPU (分时复用CPU资源)。而当下常见CPU为纳秒级,1秒可以执行大约10亿条指令。由于人眼的反应速度是毫秒级,所以看似同时在运行。

实质上,并发是宏观并行,微观串行!

那么在一个并发环境下,执行的并发程序,我们怎么刻画这样的程序呢?于是,进程的定义就孕育而生了,它准确的刻画了一个在并发环境下的一个并行程序的执行。

进程:
  进程是具有独立功能的程序,是关于某个数据集合上的一次运行活动。进程还是系统进行资源分配基本的单位、基本的执行单元,也是CPU调度的单位。

如下:

  • 进程是程序的一次执行过程


  • 进程是正在运行的程序的抽象


  • 因为虚拟化的存在,进程将一个CPU变化出多个虚拟的CPU


  • 系统资源以进程为单位分配,比如内存,文件,独立的地址空间等等


  • 操作系统将CPU的控制权交给了某一个进程,让这个进程上去运行,这称之为一个调度。也就是说,操作系统通过调度,将CPU的控制权交给这个进程。



进程控制块PCB:

  • 进程控制块PCB又称为进程描述符进程属性。是操作系统专门用于管理控制进程信息的一个数据结构。


  • PCB是系统感知进程的存在的唯一标志,进程与PCB是一一对应的。


  • 该数据结构主要时记录进程的各种属性,描述该进程的动态变化过程。

进程表:
  所有进程的PCB的集合。(进程表大小往往是固定的,操作系统一般会确定最多能支持多少个进程,也就是说,操作系统的并发度最多有多少个进程可以执行)

PCB存储的信息大致有如下内容:

进程描述信息:

  • 进程标识符(Process ID),唯一,通常是一个整数。简称PID
  • 进程名,通常基于可执行文件名,不唯一。
  • 用户标识符(User ID)。
  • 进程组关系(比如记录当前进程与它的子进程或、父进程的关系)


进程控制信息:

  • 当前进程状态
  • 调度优先级(Priority)
  • 代码执行入口地址
  • 可执行文件(程序)的磁盘地址
  • 运行统计信息(执行时间,页面调度)
  • 进程间同步和通讯
  • 进程的队列指针
  • 进程的消息队列指针


所拥有的资源和使用情况:

  • 虚拟地址空间的状况
  • 打开文件列表


CPU现场信息(当进程不运行的时候,操作系统要把硬件执行信息保存在PCB中):

  • 寄存器值(通用寄存器,程序计数器PC,程序状态字PSW,栈指针)
  • 指向该进程页表的指针

上面只是列出PCB块具体要存储的信息和主要的特征,PCB块是作为一个通用的名字,在实际的操作系统中,进程控制块的名字是不一样的,但存储的信息和主要的特征都大同小异。例如,在Linux中,名字叫task_struct,在Windows中,由EPROCESS、KPROCESS、PEB三部分组成。感兴趣的可以自己去网上搜。



进程的状态:

状态 英文 含义
运行态 Running 占有CPU,并在CPU上运行。
就绪态 Ready 已经具备运行条件,但是由于没有空闲CPU,暂时不能运行。
等待态(又称为阻塞态,封锁态,睡眠态) Waiting/Blocked 因等待某一事件而暂时不能运行。例如等待I/O结果。
创建态 New 已经完成创建一个进程所必要的工作,比如分配了PID、填写了PCB。但操作系统还没有把它加入到可执行进程组中。
终止态 Terminated 终止执行后,进程进入该状态,并统计资源数据,然后进行资源回收。
挂起态 Suspend 在操作系统中,想进行一些负载调节时,会让一部分进程暂时不能运行,但这不是等待态(没有等待某个事件发生),而是挂起态,一旦进程进入挂起态,操作系统会将进程的内存空间收起来,把进程相关内容送到磁盘上保存起来。一旦我们需要继续运行那个进程时(一般称之为激活),操作系统将再从磁盘读取信息。


我们先来看看三种基本的状态模式及其转换:

(数字只是作为标记,不代表顺序)
在这里插入图片描述

2:就绪 -> 运行
  调度程序,选择一个新的进程运行。

4:运行 -> 就绪
  有可能是运行的进程用完了系统给它分配的时间片(超时),或是一个高优先级进程进入就绪状态,要抢占正在运行的进程。

6:运行 -> 等待
  当一个程序等待某个事件发送时。例如:请求OS服务、对资源的访问尚不能进行、等待I/O结果、等待另一进程提供信息…

5:等待 -> 就绪
  当所等待的事件发生时,那么一个等待态便进入了就绪态。


我们再先来看看五种基本的状态模式及其转换:

(数字只是作为标记,不代表顺序)
在这里插入图片描述

1:创建 -> 就绪
  完成创建一个进程所必要的工作,送入就绪态。

3:运行 -> 终止
  当进程运行结束后,进入终止态,统计资源数据,进行资源回收。


我们再先来看看七种基本的状态模式及其转换(挂起态有两种):

(数字只是作为标记,不代表顺序)在这里插入图片描述

7:创建 -> 就绪挂起
  当操作系统负载过重,将刚创建的进程送入就绪态

8:就绪 -> 就绪挂起
  当操作系统负载过重,把一部分就绪的进程进入就绪挂起,减轻系统负担。

9:就绪挂起 -> 就绪
  把就绪挂起的程序激活,送入就绪态

10:等待 -> 等待挂起
  如果将就绪的进程送入就绪挂起,减轻负担后,系统的负载还是太大,则会将处于等待态的进程送入等待挂起,进一步减轻系统负载。

11:等待挂起 -> 等待
  把等待挂起的进程激活,送入等待态。

12:等待挂起 -> 就绪挂起
  如果等待挂起的进程在激活之前,所等待的事件发生时量,则进入就绪挂起态。

13:运行 -> 就绪挂起
  将正在运行的进程,送入就绪挂起态。

具体可以查看这个https://blog.csdn.net/freeelinux/article/details/53562592或者是自己查相关资料


简化图如下
在这里插入图片描述


进程队列

  • 操作系统将不同状态的进程进行管理而建立一个或多个队列


  • 队列元素为进程控制块PCB


  • 伴随进程状态的改变,其PCB从一个队列进入另一个队列


  • 由于等待态进程其等待的原因不同,所以会有很多个等待队列


  • 就绪态的队列也可以有多个


  • 单CPU情况下,运行态队列中只有一个进程,所以这里就没有画出来。

在这里插入图片描述

下面给出了一个大致的五状态进程模型的队列模型:
在这里插入图片描述
创建好的进程,经过许可,进入就绪态队列。就绪队列的进程经过调度选中,进入CPU运行。

  如果运行完成,则释放内存,退出。

  如果运行完CPU给他分配的时间片,则回到就绪队列。

  如果运行过程中遇到等待事件,则进入到相应的等待事件队列,如果事件发生,则回到就绪队列。



进程控制
进程控制操作完成进程各状态之间的转换,由具有特定功能的原语完成,例如:

  • 进程创建原语
  • 进程撤销原语
  • 阻塞原语
  • 唤醒原语
  • 挂起原语
  • 激活原语
  • 改变进程优先级原语

原语(Primitive)
完成某种特定功能的一段程序(如:创建,撤销,阻塞等),且具有不可分割性或不可中断性。
(即原语的执行必须是连续的,在执行过程中不允许被中断,如,需要操作系统通过屏蔽中断等一些操作来达到效果)

进程的创建大致流程

  • 给新进程分配一个唯一标识以及进程控制块
  • 为进程分配地址空间(如果在虚拟存储下,则是给一个虚拟的地址空间)
  • 初始化进程控制块(设置默认值,如:状态为New)
  • 创建好后,设置(插入)相应的队列指针(如:把新进程加到就绪队列链表中)

    在不同系统中,创建进程的函数(原语)的具体操作可能会有一点点不同,但大致流程都一样:

       - Unix/Linux:fork()函数/exec()函数

       - Windows:CreateProcess()函数

进程的撤销大致流程

  • 收回进程所占有的资源(如:关闭打开的文件,断开网络连接,回收分配的内存等…)
  • 撤销该进程的PCB(进程描述符)

    在不同系统中,撤销进程的函数(原语)的具体操作可能会有一点点不同,但大致流程都一样:

      - Unix/Linux:exit()函数

      - Windows:TerminateProcess()函数

进程阻塞

  • 处于运行状态的进程,在其运行的过程中期待某一事件发生,如:等待键盘输入,等待磁盘数据传输完成、等待其他进程发送消息等…当这些被等待的事件未发生时,由进程自己执行阻塞原语,使自己由运行态变成阻塞态。

    在不同系统中,进程阻塞的函数(原语)的具体操作可能会有一点点不同,但大致流程都一样:

      - Unix/Linux:wait()函数

      - Windows:WaitForSingleObject()函数



我们先把Unix的进程控制操作函数(原语)单独拎出来,它们以系统调用的形式作为一个系统接口呈现给用户程序,由用户来调用

函数/原语 简介
fork() 通过复制调用进程来建立新的进程,是最基本的进程建立过程
exec() 包括一系列系统调用,他们都是通过用一段新的程序代码覆盖原来的地址空间,实现进程执行代码的转换
wait() 提供初级进程同步操作,能使一个进程等待另外一个进程的结束
exit() 用来终止一个进程的运行

UNIX下FORK()实现

  • 为子进程分配一个空闲的进程描述符PCB(在Unix中又称proc结构)
  • 分配给子进程唯一标识符(PID)
  • 分配地址空间,以一次一页的方式把父进程的地址空间的内容完全复制拷贝给子进程
  • 然后将会从父进程处继承共享资源,如:打开的文件和当前工作目录等
  • 将子进程的状态设为就绪,插入到就绪队列中
  • 给子进程返回标识符0,给父进程返回子进程的进程标识符PID

在fork()函数执行完后,将会有两个进程,一个父进程,一个子进程。

  注意:我们前面说到,在Unix中,fork()函数会在分配地址空间时,以一次一页的方式来复制父进程的地址空间。这样做有一个弊端,就是父进程把自己所有的内容拷贝给子进程,但是子进程不一定的需要这些内容。通常情况下父进程创建子进程是让子进程去做与父进程不同的工作,所以在Unix中,子进程一般会接着执行exec()函数,来把父进程拷贝过来的地址空间覆盖掉。可以看到这样了浪费了很多时间和空间。

  Linux中改善了fork()函数,利用写时复制技术COW(Copy-On-Write),加快了创建进程速度。Linux中改善了fork()函数,利用写时复制技术COW(Copy-On-Write),加快了创建进程速度。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!