目录
一. 进程的概念、组成、特征
1. 进程的概念
程序:静态的,存放在磁盘里的可执行文件,是一系列指令的集合。如QQ.exe等
进程(progress):动态的,是程序的一次执行过程,一个程序可以产生多个进程。
既然一个程序可以产生多个进程,那么操作系统是如何区分这些看似相同的进程的呢?原来,当进程被创建的时候,操作系统会为每个进程创建一个PID(progress ID)根据这些唯一的ID就可以实现区分进程的功能。
操作系统将PID以及管理程序所需要的其他信息均存放在一个特殊的数据结构PCB(progress control black,进程控制块)中。
2. 进程的组成
进程主要由以下三个部分组成,其中PCB是给操作系统用的,程序段、数据段是供进程自己使用的,如下图所示:
PCB:PCB是进程存在的唯一标志,当进程被创建时,操作系统为其创建PCB,当进程结束时,会回收其PCB。
PCB存储的主要信息:
我们上面所说的”进程“实际上应该叫做”进程实体“,进程是一个动态过程,进程实体是静态的。进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。不过一般不做区分。
3. 进程的特征
进程主要有以下特征: 结构性、动态性、并发性、独立性、异步性.
结构性:每个进程都会有一个PCB,进程(实体)由PCB、程序段、数据段构成。
并发性:指多个进程实体同存于内存中,且能在一段时间内同时运行。这里应注意,引入进程的目的也正是为了使其进程实体能和其它进程实体并发执行;而程序(没有建立 PCB)是不能并发执行的。
动态性: 进程是程序的一次执行过程,动态地产生以及消亡,这是进程最基本的特性。
独立性:进程(实体)是一个能独立运行、独立分配资源和独立接受调度的基本单位。凡未建立 PCB 的程序都不能作为一个独
立的单位参与运行。
异步性: 进程按各自独立的、 不可预知的速度向前推进。操作系统会采用进程同步机制来解决异步问题。
二. 进程状态的转换以及进程组织方式
1. 进程的状态
因为进程的执行在时间上是不连贯的,所以进程就会有多种状态,其中就绪态、执行态、阻塞态是三种最基本的状态。除此之外进程还可能会有创建态以及终止态。
(1)创建态:在进程被创建时他的状态是创建态,这个时候操作系统为进程分配了一些资源,初始化了PCB。但是因为资源不完整所以还不能运行。
(2)就绪态(Ready):创建态结束后,进程便进入“就绪态”,处于就绪态的进程已经具备运行条件,但由于没有空闲CPU,就暂时不能运行。
(3)执行态:当CPU空闲时,他会在就绪队列中选择一个就绪态的进程让他上处理机运行,这时程序就进入了执行态。
(4)阻塞态:正在执行的进程可能会遇到一些事件(请求IO,申请缓存空间等)而无法继续执行下去,此时进程进入了阻塞态,这个时候CPU会让这个进程下处理机并运行另一个处于就绪态的进程。
(5)终止态:一个进程可以执行 exit 系统调用,请求操作系统终止该进程。此时该进程会进入“终止态”,操作系统会让该进程下CPU,并回收内存空间等资源,最后还要回收该进程的PCB。当终止进程的工作完成之后,这个进程就彻底消失了。
下面用一张图说明这几种状态之间的转化情况:
这里我们需要注意一下:就绪态没有办法变为阻塞态,阻塞态也没有办法变为执行态,因为阻塞态是主动请求发生的,必须要进程在运行中才能发出这种请求。
2. 进程的组织方式
进程PCB中,会有一个变量 state 来表示进程的当前状态。如:1表示创建态、2表示就绪态、3表示运行态…为了对同一个状态下的各个进程进行统一的管理,操作系统会将各个进程的PCB组织起来。主要的进程组织方式有链接方式以及索引方式两种。
链接方式:这是把具有同一状态的 PCB,用其中的链接字链接成一个队列。这样,可以形成绪队列、若干个阻塞队列和空白队列等。对其中的就绪队列常按进程优先级的高低排列,把优先级高的进程的 PCB 排在队列前面。此外,也可根据阻塞原因的不同而把处于阻塞状态的进程的 PCB 排成等待 I/O 操作完成的队列和等待分配内存的队列等。
索引方式:系统根据所有进程的状态建立几张索引表。例如,就绪索引表、阻塞索引表等,并把各索引表在内存的首地址记录在内存的一些专用单元中。在每个索引表的表目中,记录具有相应状态的某个 PCB 在 PCB 表中的地址。
三. 进程控制
1. 基本概念
在书中,进程控制的定义是这样的:进程控制是进程管理中最基本的功能。它用于创建一个新进程,终止一个已完成的进程,或终止一个因出现某事件而使其无法运行下去的进程,还可负责进程运行中的状态转换。其实简单来说,进程控制就是为了实现进程状态之间的转换。
那么进程控制是怎么实现的呢?进程控制一般来说是通过OS内核中的原语来实现的。原语(Primitive)是由若干条指令组成的,用于完成一定功能的一个过程,它是一个不可分割的基本单位,因此,在执行过程中不允许被中断。原子操作在管态下执行,常驻内存。
为什么要使用原子操作(一气呵成)呢?如果系统对进程的控制如不使用原语,就会造成其状态的不确定性,从而达不到进程控制的目的。比如说将执行态变为阻塞态需要两步,首先将state的值改变之后再将此PCB放在阻塞队列,如果非原子操作,在改变state值之后发生中断,那么在执行队列就出现了阻塞态的PCB,这是不正确的。
如何保证操作的原子性呢?这里我们需要引出两个特权指令:开中断指令和关中断指令。顾名思义,开中断就是将中断打开,关中断就是将中断关闭。我们将要执行的操作放在开中断与关中断指令的中间,CPU执行了关中断指令之后,就不再例行检查中断信号,直到执行开中断指令之后才会恢复检查。这样,关中断、开中断 之间的这些指令序列就是不可被中断的,这就实现了“原子性”。
2. 进程创建原语
引起进程创建的事件:
(1) 用户登录。在分时系统中,用户在终端键入登录命令后,如果是合法用户,系统将为该终端建立一个进程,并把它插入就绪队列中。
(2) 作业调度。在批处理系统中,当作业调度程序按一定的算法调度到某作业时,便将该作业装入内存,为它分配必要的资源,并立即为它创建进程,再插入就绪队列中。
(3) 提供服务。当运行中的用户程序提出某种请求后,系统将专门创建一个进程来提供用户所需要的服务。
(4) 应用请求。在上述三种情况下,都是由系统内核为它创建一个新进程;而第 4 类事件则是基于应用进程的需求,由它自己创建一个新进程,以便使新进程以并发运行方式完成特定任务。
3. 进程终止原语
引起进程终止的事件:1) 正常结束 2) 异常结束 3) 外界干预
进程终止原语所执行的步骤:
(1) 根据被终止进程的标识符,从 PCB 集合中检索出该进程的 PCB,从中读出该进程的状态。
(2) 若被终止进程正处于执行状态,应立即终止该进程的执行,并置调度标志为真,用于指示该进程被终止后应重新进行调度。
(3) 若该进程还有子孙进程,还应将其所有子孙进程予以终止,以防它们成为不可控的进程。
(4) 将被终止进程所拥有的全部资源,或者归还给其父进程,或者归还给系统。
(5) 将被终止进程(PCB)从所在队列(或链表)中移出,等待其他程序来搜集信息。(这样就由其他状态转为终止态)
4. 进程的阻塞与唤醒
引起进程阻塞(block)的事件:需要等待系统分配资源、需要等待相互合作的进程完成工作。
进程阻塞原语所执行的步骤:找到相应的PCB-->保护现场并将PCB设置为阻塞态,暂停进程的运行-->将PCB插入到相应的队列中(运行态变为阻塞态)。
引起进程唤醒(wakeup)的事件:引起阻塞的事件已经解决(何事引起的阻塞就要由何事进行唤醒,所以阻塞原语与唤醒原语往往是成对出现的)。
进程唤醒原语所执行的步骤:把被阻塞的进程从等待该事件的阻塞队列中移出-->将其PCB 中的现行状态由阻塞改为就绪-->然后再将该 PCB 插入到就绪队列中。(阻塞态变为就绪态)。
5. 进程的切换
进程的切换我们可以理解为进程的执行态与就绪态之间的相互转换,或者说不同进程之间的切换。
引起切换的事件:当前进程时间片到、有更高优先级的进程到达、当前进程主动阻塞、当前进程终止。
切换原语执行的步骤:将运行环境存储到PCB-->将PCB更换存储队列选择其他PCB执行并更新其状态-->根据PCB存储的运行环境恢复其运行环境。
无论哪个进程控制原语,要做的无非三类事情:
1. 更新PCB中的信息(a. 所有的进程控制原语一定都会修改进程状态标志 b. 剥夺当前运行进程的CPU使用权必然需要保存其运行环境 c.某进程开始运行前必然要恢复期运行环境)。
2. 将PCB插入合适的队列。
3. 分配/回收资源。
四. 进程通信
顾名思义,进程通信就是指进程之间的信息交换。进程是分配系统资源的单位(包括内存地址空间),因此各进程拥有的内存地址空间相互独立。同时为了保证安全,一个进程不能随意的访问另一进程的资源,但有时进程通信又是必要的,所以操作系统提供了共享存储、消息传递、管道通信三种方式来实现进程之间的通信。
1. 共享存储
在共享存储这一形式中,两个进程对于某一共享内存的访问必须是互斥(不能同时访问)的。共享存储又可以进一步分为基于数据结构的共享以及基于存储区的共享。
基于数据结构的共享:在这种通信方式中,要求诸进程公用某些数据结构,借以实现诸进程间的信息交换。比如共享空间里只能放一个长度为10的数组。这种共享方式速度慢、限制多,是一种低级通信方式。
基于存储器的共享:为了传输大量数据,在存储器中划出了一块共享存储区,诸进程可通过对共享存储区中数据的读或写来实现通信,数据的形式、存放位置都由进程控制,而不是操作系统。相比之下,这种共享方式速度更快,是一种高级通信方式。
2. 消息传递
消息传递的方式是现在应用最广泛的一种进程通信方式,进程间的数据交换以格式化的消息(Message)为单位。进程通过操作系统提供的“发送消息/接收消息”两个原语进行数据交换。运用这种方式不仅实现了大量数据的传递而且向用户透明,隐藏了其中的实现细节,因此应用较为广泛。消息传递又可以分为直接通信方式和间接通信方式。
直接通信方式:消息直接挂到接收进程的消息缓冲队列上。
间接通信方式:消息要先发送到中间实体(信箱)中,因此也称“信箱通信方式”。
3. 管道通信
所谓“管道”,是指用于连接一个读进程和一个写进程以实现它们之间通信的一个共享文件,又名 pipe 文件。其实就是在内存中开辟一个大小固定的缓冲区。
1. 管道只能采用半双工通信,某一时间段内只能实现单向的传输。如果要实现双向同时通信,则需要设置两个管道。
2. 各进程要互斥地访问管道。
3. 数据以字符流的形式写入管道,当管道写满时,写进程的write()系统调用将被阻塞,等待读进程将数据取走。当读进程将数据全部取走后,管道变空,此时读进程的read()系统调用将被阻塞。
4. 如果没写满,就不允许读。如果没读空,就不允许写。
5. 数据一旦被读出,就从管道中被抛弃,这就意味着读进程最多只能有一个,否则可能会有读错数据的情况。
如有雷同,纯属总结