进程
进程是一个可并发执行的具有独立功能的程序关于某个数据集合的一次执行过程,也是操作系统进行资源分配和保护的基本单位。
它具有如下属性:
结构性:进程包含了数据集合和运行于其上的程序,为了描述和记录进程的动态变化过程使其能正确运行,还需配置一个进程控制块,所以,每个进程至少有三要素组成:程序块、数据块和进程控制块。
共享性:同一程序同时运行于不同数据集合上时,构成不同的进程。或者说,多个不同的进程可以共享相同的程序,所以,进程和程序不是一一对应的。
动态性:进程是程序在数据集合上的一次执行过程,是动态概念,同时,它还有生命周期,由创建而产生,由调度而执行,由撤销而消亡;而程序是一组有序指令序列,是静态概念,所以,程序作为一种系统资源是永久存在的。
独立性:进程既是系统中资源分配和保护的基本单位,也是系统调度的独立单位(单线程进程)。凡是未建立进程的程序,都不能作为独立单位参与运行。通常,每个进程都可以各自独立的速度在CPU 上推进。
制约性:并发进程之间存在着制约关系,进程在进行的关键点上需要相互等待或互通消息,以保证程序执行的可再现性和计算结果的唯一性。
并发性:进程可以并发地执行,进程的并发性能改进资源利用率和提高系统效率。
进程的状态和转换
基本状态:
运行态:进程占有处理器正在运行。
就绪态:进程具备运行条件,等待系统分配处理器以便运行。
等待态:又称为阻塞态或睡眠态,指进程不具备运行条件,正在等待某个事件的完成。
5种状态:
进程的内存映像
当一个程序进入计算机的主存储器进行计算就构成了进程,主存储器中的进程到底是如何组成的?操作系统中把进程物理实体和支持进程运行的环境合称为进程上下文(process context)。当系统调度新进程占有处理器时,新老进程随之发生上下文切换,因此,进程的运行被认为是在进程的上下文中执行的。在操作系统中,进程上下文包括三个组成部分:
用户级上下文:由用户进程的程序块、用户数据块(含共享数据块)和用户堆栈组成的进程地址空间。
系统级上下文:包括进程的标识信息、现场信息和控制信息,进程环境块,以及系统堆栈等组成的进程地址空间。
寄存器上下文:由程序状态字寄存器、各类控制寄存器、地址寄存器、通用寄存器、用户栈指针等组成。
进程的内存映像可以很好地说明进程的组成。简单的说,一个进程映像(ProcessImage)包括:
进程程序块,即被执行的程序,规定了进程一次运行应完成的功能。通常它是纯代码,作为一种系统资源可被多个进程共享。
进程数据块,即程序运行时加工处理对象,包括全局变量、局部变量和常量等的存放区以及开辟的工作区,常常为一个进程专用。
系统/用户堆栈,每一个进程都将捆绑一个系统/用户堆栈。用来解决过程调用或系统调用时的信息存储和参数传递。
进程控制块,每一个进程都将捆绑一个进程控制块,用来存储进程的标志信息、现场信息和控制信息。进程创建时,建立进程控制块;进程撤销时,回收进程控制块,它与进程一一对应。可见每个进程有四个要素组成:控制块、程序块、数据块和堆栈。
进程控制块
每一个进程都有一个也只有一个进程控制块PCB(Process Control Block),进程控制块是操作系统用于记录和刻画进程状态及有关信息的数据结构,也是操作系统掌握进程的唯一资料结构,是操作系统控制和管理进程的主要依据。它包括了进程执行时的情况,以及进程让出处理器后所处的状态、断点等信息。一般说,进程控制块包含三类信息:
标识信息。用于唯一地标识一个进程,常常分为由用户使用的外部标识符和被系统使用的内部标识号。几乎所有操作系统中进程都被赋予一个唯一的、内部使用的数值型的进程号,操作系统的其他控制表可以通过进程号来交叉引用进程控制表。常用的标识信息包括进程标识符、父进程的标识符、用户进程名、用户组名等。
现场信息。用于保留一个进程在运行时存放在处理器现场中的各种信息,任何一个进程在让出处理器时必须把此时的处理器现场信息保存到进程控制块中,而当该进程重新恢复运行时也应恢复处理器现场。常用的现场信息包括:通用寄存器的内容、控制寄存器(如PSW 寄存器)的内容、用户堆栈指针、系统堆栈指针等。
控制信息。用于管理和调度一个进程。
常用的控制信息包括:
1)进程调度相关信息,如进程状态、等待事件和等待原因、进程优先级、队列指引元等;
2)进程组成信息,如正文段指针、数据段指针;
3)进程间通信信息,如消息队列指针、信号量等互斥和同步机制;
4)进程在辅存储器内的地址;
5)CPU资源的占用和使用信息,如时间片余量、进程己占用CPU 的时间、进程己执行的时间总和,记账信息;
6)进程特权信息,如在内存访问权限和处理器状态方面的特权;
7)资源清单,包括进程所需全部资源、已经分得的资源,如主存资源、I/O 设备、打开文件表等。
进程的控制
进程的控制包括:创建进程、阻塞进程、唤醒进程、挂起进程、激活进程、终止进程和撤销进程等。
这些控制和管理功能是由操作系统中的原语来实现的。
原语(Primitive)是在管态下执行、完成系统特定功能的过程。
原语和机器指令类似,其特点是执行过程中不允许被中断,是一个不可分割的基本单位,原语的执行是顺序的而不可能是并发的。系统对进程的控制如不使用原语,就会造成其状态的不确定性,从而,达不到进程控制的目的。
原语和系统调用都使用访管指令实现,具有相同的调用形式;但原语由内核来实现,而系统调用由系统进程或系统服务器实现;原语不可中断,而系统调用执行时允许被中断,甚至有些操作系统中系统进程或系统服务器干脆在用户态运行;通常情况下,原语提供给系统进程或系统服务器使用(反之决不会形成调用关系),系统进程或系统服务器提供系统调用给系统程序(和用户)使用,而系统程序提供高层功能给用户使用,例如,语言编译程序提供语句供用户解决应用问题。
进程的创建过程描述如下:
在主进程表中增加一项,并从 PCB 池中申请一个空白PCB(在UNIX/Linux中,分配一个
task_struct)。
为新进程的进程映像分配地址空间。对于进程创建操作还需要传递环境变量,构造共享地址空间。
为新进程分配资源,除内存空间外,还有其他各种资源。
查找辅助存储器,找到进程正文段并装入到进程地址空间的正文区。
初始化进程控制块(如状态、PSW、栈等),为新进程分配一个唯一的进程标识符,
把进程加入某一就绪进程队列(这时子进程就绪),或直接将进程投入运行(这时父进程就绪)。
通知操作系统的某些模块,如记账程序、性能监控程序。
进程的创建来源于以下四个事件:
提交一个批处理作业。
在终端上一个交互式作业登录。
操作系统创建一个服务进程。
存在的进程创建新的进程。
进程的阻塞是指使一个进程让出处理器,去等待一个事件,如等待资源、等待I/O完成、等待一个事件发生等,通常进程自己调用阻塞原语阻塞自己,所以,是进程自主行为,是一个同步事件。
进程阻塞的步骤如下:
停止进程执行,保存现场信息到 PCB。
修改进程控制块的有关内容,如进程状态由运行改为等待等。
把修改状态后的进程控制块加入相应等待进程队列。
接着便应转入进程调度程序去调度其他进程运行。
进程唤醒的步骤如下:
从相应的等待进程队列中取出进程控制块。
修改进程控制块的有关信息,如进程状态改为就绪。
把修改后的进程控制块加入有关就绪进程队列。
一个进程完成了特定的工作或出现了严重的异常后,操作系统则收回它占有的地址空间和进程控制块,此时就说撤销了一个进程。
当出现了引起挂起的事件时系统或进程利用挂起原语把指定进程或处于阻塞状态的进程挂起。其执行过程大致如下:检查要被挂起进程的状态,若处于活动就绪态就修改为挂起就绪,若处于阻塞态,则修改为挂起阻塞。被挂起进程PCB 的非常驻部分要交换到磁盘对换区。
当系统资源尤其是内存资源充裕或进程请求激活指定进程时,系统或有关进程会调用激活原语把指定进程激活,该原语所做的主要工作是:把进程PCB 非常驻部分调进内存,然后修改它的状态,挂起等待态改为等待态,挂起就绪态改为就绪态,并分别排入相应队列中。
注意,挂起原语既可由进程自己也可由其他进程调用,但激活原语却只能由其他进程调用。
本文出自 “SeaSky” 博客,谢绝转载!