概念:
进程的多个定义:
进程是程序的一次执行过程
进程是一个程序及其数据在处理机上顺序执行时所发生的活动
进程时具有独立功能的程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位
上面所说的三个不同的定义都在强调一个点:进程是一个运行过程,它是动态的过程而不是静态的事物
在多道程序环境下,允许多个程序并发执行,此时他们将失去封闭性,并具有间断性以及不可再现性的特征。为此引入了进程的概念,一个进程代表一个允许的程序。进程是动态的运行过程,而程序是静态的代码。进程可以让我们更好的描述和控制程序的并发执行,实现操作系统的并发性和共享性。
为了让参与并发的每个进程都能独立地运行,必须为每个进程配置一个专门的数据结构,我们将这个数据结构称为进程控制块(PCB)。系统利用PCB来描述进程的基本情况和运行状态,进而控制和管理进程。同时,程序,相关数据段,PCB三个部分共同构成了进程实体(又称进程映像)
所谓的创建进程,实际上是创建进程实体中的PCB,而撤销进程,实际上是撤销进程实体中的PCB。进程映像是静态的,进程是动态的。
PCB是进程存在的唯一标志
引入进程实体的概念之后,我们可以把传统操作系统的进程定义为:"进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位"
特征:
动态性。进程是程序的一次执行,有着创建,活动,暂停,终止等过程,具有一定的生命周期。动态性是进程最基本的特征。
并发性。多个进程实体同存于内存中,能在一段时间内同时运行。引入进程的目的就是使进程能和其他进程并发执行。并发性是进程的重要特征,也是操作系统的重要特征。
独立性。指每个进程实体都能独立运行,独立获得资源和独立接受调度。凡是没有建立PCB的程序,都不能作为一个独立运行的单位参与运行
异步性。由于进程的相互制约,使得进程按各自独立的,不可预测的速度向前推进。异步性会导致结果的不可再现性,因此操作系统中必须配置相应的进程同步机制。
进程是由多道程序的并发执行而引出的,它和程序是两个截然不同的概念。(一个是爹一个是儿子,很多个爹并发,然后引出一个儿子的概念)进程的基本特征是对比单个程序的顺序执行提出的,也是对进程管理提出的基本要求。
进程的状态
进程一共有5种状态,常用的是前三种:
运行态。进程正在处理机上运行。在单处理机中,每个时刻都只有一个进程处于运行状态。
就绪态。进程获得了除了处理机意外的一切它所需要的资源,只要得到处理机,这个进程就能立即执行。系统中处于就绪态的进程可以有很多个,通常将它们排成一个队列,称为就绪队列
阻塞态。又称为等待态,进程正在等待某一时间而暂停运行,如等待某资源为可用(不包括处理机)或等待输入/输出完成。即使处理机空闲,该程序也不能运行。系统通常将处于阻塞态的进程也排成一个队列,甚至根据阻塞原因的不同,设置多个阻塞队列。
创建态。进程正在被创建,尚未转到就绪态。创建进程需要多个步骤:
申请一个空白PCB
向PCB中填写用于控制和管理进程的信息
为该进程分配运行时所必须的资源
把该进程转入就绪态并插入就绪队列
但是,如果进程所需的资源(处理机以外的)不能被满足,那么创建工作就尚未完成,这个时候进程所属的状态就是创建态
结束态。进程正从系统中消失,可能时进程正常结束或其他原因退出运行,进程需要结束运行时,系统首先将这个进程设置为结束态,然后进一步处理资源释放和回收工作
进程状态之间的转换
1.就绪态→运行态:处于就绪态的进程被调度后,获得处理机资源(处理机分配时间片),于是进程就从就绪态变成了运行态
2.运行态→就绪态:处于运行态的进程在时间片用完之后,不得不让出处理机,从而进程由运行态转为就绪态。
3.运行态→阻塞态:进程请求某一资源的使用和分配或等待某一时间的发生时,它就从运行态转为阻塞态。这个状态的转变是进程的主动转换,而不是被动的获得什么或丢失什么而进行的状态转换
4.阻塞态→就绪态:进程等待的事件或资源到来的时候,中断处理程序必须把相应进程的状态由阻塞态转换为就绪态。(比如所中断结束的时候,中断处理程序就要干活了)
5.创建态→就绪态:当进程获得了除了处理机以外的所有资源的时候,进程的状态就从创建态变为了就绪态
6.运行态→结束态:当进程结束运行或出现错误而终止运行的时候,操作系统就把这个进程的状态设置为结束态,然后处理资源释放和回收的工作
1.进程控制块(PCB)------十分重要
进程创建的时候,操作系统为它新建一个PCB,该结构之后常驻内存,任意时刻都可以存取,并在进程结束的时候删除。PCB是进程实体的一部分,是进程存在的唯一标志。
进程执行的时候,系统通过其PCB了解进程的现行状态,一边操作系统对其进行控制和管理;进程结束的时候,系统收回其PCB,该进程随之消亡
PCB的主要用处如下:
当操作系统想要调度某个进程运行的时候,要从这个进程的PCB中查出其这个进程现在的状态和优先级
在调度到某个进程之后,要根据其PCB中所保存的处理机的状态信息,设置该进程恢复运行的现场,并根据PCB中的程序和数据的内存地址,找到这个进程的程序和数据
进程在运行过程中,当需要和与之合作的进程实现同步、通信或者是访问文件的时候,也需要访问PCB
当进程由于某种原因而暂停运行的时候(可以是出现了异常,有了中断事件,或者只是单纯的分配的时间片到了),需要将断点的处理机状态(也可以说是处理机环境)保存在PCB中
在进程的整个生命周期中,系统总是通过PCB对进程进行控制的,换句话说就是:系统只有通过PCB才能感知到进程的存在
PCB实例的图表如下:
进程描述信息 | 进程控制和管理信息 | 资源分配清单 | 处理机相关信息 |
---|---|---|---|
进程标识符(PID) | 进程当前状态 | 代码段指针 | 通用寄存器值 |
用户标识符(UID) | 进程优先级 | 数据段指针 | 地址寄存器值 |
代码运行入口地址 | 堆栈段指针 | 控制寄存器值 | |
程序的外村地址 | 文件描述符 | 标志寄存器值 | |
进入内存时间 | 键盘 | 状态字 | |
处理机占用时间 | 鼠标 | ||
信号量使用 |
下面对每一列中的重要内容进行描述:
进程描述信息:
进程标识符:标志各个进程,每个进程都有一个唯一的标识号
用户标识符:进程归属的用户,用户标识符主要为共享和保护这两个功能服务
进程控制和管理信息:
进程当前状态:描述进程的状态信息,作为处理机分配调度的依据(进程的5个状态)
进程优先级:描述进程抢占处理机的优先级,优先级高的进程可以先获得处理机
资源分配清单:用于说明有关内存地址空间或虚拟地址空间的状况,所打开文件的列表和所使用的输入/输出设备信息
处理机相关信息:也成为处理机的上下文,主要指处理机中各个寄存器的值。当进程处于执行态的时候,处理机的许多信息都在寄存器里面。当进程被切换走的时候,处理机的上下文都应该被保存在PCB里面,以便在该进程重新启动的时候,能从断点直接开始继续执行程序
为了方便进程的调度和管理,需要将各个进程的PCB用适当的方法组织起来。目前常用的组织方法有两种:
连接方式:将同一状态的进程(PCB)链接成一个队列(也许是链表的形式?)不同状态对应不同的队列
索引方式:将同一状态的进程(PCB)组织在一个索引表里面,索引表的表项指向相应的PCB,不同状态对应不同的索引表
2.程序段
程序段指能被进程调度到处理机中执行的代码段。程序可被多个进程运行,也就是说多个进程可以运行同一个程序
3.数据段
指一个进程对应的程序加工处理的数据,可以是原始数据也可以是中间和结果数据
对系统中的所有进程实施有效的管理,具有创建新进程,撤销已有进程,实现进程状态转换等功能。一般把用于控制进程的程序段称为原语,原语的特点是执行期间不允许中断。
1.进程的创建
允许一个进程创建另一个进程。被创建的进程是子进程,另一个就是父进程。子进程可以继承父进程拥有的所有资源。子进程被撤销的时候,要把从父进程那里获得的资源还给父进程。如果直接撤销父进程,子进程一般也会被撤销。
创建进程会用到的原语是创建原语,其内容如下:
为新进程分配一个唯一的进程标识号,并申请一个空白PCB(PCB是有限的)。若PCB申请失败,则创建失败
为进程分配其运行所需要的资源,如内存、I/O设备和CPU时间等。这些资源可以从操作系统中获得,也可以从它的父进程中获得。如果资源不够,那么这个资源就处于创建态等待资源够的时候进行分配
初始化PCB,主要包括初始化标志谢谢、初始化处理机状态信息和初始化处理机控制信息,以及设置进程的优先级等
如果进程就绪态队列能够接纳新的进程,那么就把新进程放到队列里面等待被调度运行
2.进程的终止
可以引起进程终止的事件主要有:
正常结束,进程任务已经完成并准备退出程序
异常结束,标识进程在运行的时候,发生了某种异常事件,让程序无法继续运行下去。
外界干预,指进程应外界的请求而停止运行,如操作系统干预(一般都是发生了中断,然后操作系统进场)
终止进程用到的原语是终止原语,其内容如下:
根据被终止进程的标识符,检索出该进程的PCB,从中读出这个进程的状态
如果被终止进程处于运行态,就立刻终止这个进程的执行,将处理机资源分配给别的进程
若该进程还有子进程,则把其子进程全部终止
将这个进程的所有资源全部释放或归还给其父进程
将该PCB从所在队列(索引表)中删除
3.进程的阻塞和唤醒
进程主动使用阻塞原语使自己的状态从运行态变为阻塞态。阻塞原语的执行过程如下:
找到将要被阻塞进程的标识号对应的PCB
若该进程为运行态,则保护其现场(存储处理机上下文),将其状态转为阻塞态,停止运行
把这个PCB插入相应事件的等待队列,将处理机资源调度给其他就绪态的进程
当被阻塞进程所等待的事件发生的时候,由别的进程调用唤醒原语将处于阻塞态的进程唤醒,唤醒原语的执行过程如下:
在该事件的等待队列中找到相应进程的PCB
将其从等待队列中移出,并设置其状态为就绪态
把该PCB插入就绪队列,等待处理机的调用(或是等待调度程序的调度)
指进程之间的信息交换。此处介绍三个高级通信方法:
1.共享存储
通信的进程之间存在一块可以直接访问的共享空间,通过对这片空间进行读写操作实现进程之间的信息交换。在对共享空间进行读写的时候,需要使用同步互斥工具(PV操作)(即共享空间是一个临界资源)来防止两边一起读或者是一起写。共享存储又分为两种:
基于数据结构的共享,为低级方式的共享
基于存储区的共享,为高级方式的共享
操作系统只负责为通信进程提供可以共享使用的存储空间和互斥工具。
进程空间一般都是独立的,进程运行期间一般不能访问其他进程的空间,想让两个进程共享空间,必须通过特殊的系统调用实现,而进程内的线程是自然共享进程空间的
2.消息传递
进程间的数据交换以格式化的消息为单位。如果通信的进程之间不存在可以直接访问的共享空间,就必须利用操作系统提供的消息传递方式实现进程通信。进程之间通过操作系统提供的发送消息和接收消息两个原语进行数据交换。这个是当前应用最广泛的进程间通信机制。
直接通信方式:发送进程直接把消息发送给接受进程,并将它挂在接收进程的消息缓冲队列上面,接收进程从消息缓冲队列中获得消息
间接通信方式:发送进程把消息发送给某个中间实体,接收进程从中间实体中拉取消息。这种中间实体一般被称为信箱。这个方式被广泛的运用在计算机网络中
3.管道通信
所谓管道,是指用于链接一个读进程和一个写进程以实现它们之间的通信的一个共享文件,又名为pipe文件。向管道(共享文件)提供输入的发送进程,以字符流形式将大量的数据写入管道;而接受管道输出的接受进程(读进程)从管道中接受数据。为了协调双方的通信,管道机制必须提供以下三方面的协调能力:互斥,同步和确定对方的存在
从管道读取数据是一次性操作,数据一旦被读取,就释放空间以便写更多的数据。管道只能采用半双工通信,即某一时刻只能单向传输。要实现父子进程的互动通信,需要定义两个管道
写进程在执行的时候,只有把管道写满了,才会让读进程进来读取数据,而缓冲区里面还有数据的时候,写进程是不会去写数据进去的。只有管道空了,写进程才开始写数据。
上一篇:状态机的Go语言实现版本