1. 实验目的
1.理解进程的基本概念及它与程序的区别和联系;
2.了解进程控制块(PCB)的一般属性和作用;
3.理解原语的含义,掌握常用的进程控制原语;
4.通过模拟实验深刻理解进程基本状态的转换过程。
2. 进程简介
一、进程的定义
与计算机领域许多别的概念类似,进程至今仍没有一个统一的定义。但我们可以从不同的角度来描述进程:
1. 进程是程序的一次执行;
2. 进程是可以和其他计算并发执行的计算;
3. 进程是一个程序极其数据在处理机上顺序执行时发生的活动;
4. 进程是程序在一个数据集合上的运行过程,是系统进行资源分配和调度的一个独立单位;
5. 进程是进程实体的一次活动。
二、进程的特点
(1)动态性
进程的实质是程序的一次执行过程,因此动态性是进程最重要的特性。同样,进程的动态性还表现在进程的生命周期上,进程因“创建”而产生,因“唤醒”而执行,因得不到资源而“阻塞”,因“撤销”而消亡,这是一个进程完整而又短暂的生命周期。
(2)并发性
并发性值不同进程的动作在时间上可以重叠,即系统内的多个进程可以并发执行。引入进程的目的正式为了使其程序能和其他进程的程序并发执行。
(3)独立性
在传统操作系统中,进程既是一个能够独立运行的基本单位,也是申请拥有系统资源的基本单位。在具有并发活动的系统中,未建立进程的程序不能作为一个独立单位运行。现在的操作系统在有进程的同时还有比其更轻量级的线程,因此独立运行的基本单位变成了线程,进程不再是一个单独的可执行实体,但需要注意的是进程仍然是一个独立拥有资源的基本单位。
(4)异步性
进程由于共享资源和协同合作是产生了相互制约的关系,造成进程执行时间的间断性,即进程以各自独立的、不可预知的速度向前推进。因此,系统必须采取措施来保证进程间能协同操作和资源共享。
(5)结构特性
为了描述进程的运动变化过程,使之能够独立运行,应为每一个进程配置一个进程控制块(Process Control Block,PCB)。这样,从结构上看,每个进程都有程序、数据和PCB三部分构成,正是这三部分构成了进程的实体,我们平时在许多情况下所说的进程都指进程实体。
3. 进程控制块PCB
虽然进程是个动态概念,但在操作系统眼里,它是可以感知并可以控制的,这靠的就是进程控制块(PCB)。PCB是系统为了描述和控制进程的运行而为进程定义的一种数据结构,它是进程实体的一部分,是进程存在的唯一标志,也是操作系统总最重要的结构体类型的数据结构。PCB中存放着操作系统所需的用于描述进程的当前情况及控制进程运行的全部信息。
一、PCB的作用
(1)标识进程的存在。系统创建进程是,就为之创建一个PCB;进程结束时,系统收回其PCB,进程便随之消亡。操作系统就是靠PCB来感知进程的存在的。
(2)位系统提供可并发执行的独立单位。这也是进程并发性和独立性的含义。PCB使一个在多道程序环境下不能独立运行的程序成为一个能独立运行的基本单位,即一个能与其他进程并发执行的进程。没有为之建立PCB的程序是不能并发执行的。或者说,操作系统是根据PCB来对并发执行的进程进行控制和管理的。
(3)为系统控制和管理进程提供所需的一切信息。
二、PCB中的信息
PCB,这个结构体变量的值也可以看成是进程的属性值。尽管不同操作系统的PCB中的内容多少不一,但多数操作系统中的PCB都含有以下用于描述和管理进程控制的信息。
(1)进程标识符。这是系统内部用于标识一个进程的唯一编号,称为进程的内部名。有的系统还允许进程创建者为进程取一个外部标识符,它通常是由字母、数字组成的符号名。
(2)进程的现行状态。它标明进程当前所处的状态,作为进程调度程序分配处理机时的依据。若进程处于阻塞状态,要在PCB中说明阻塞的原意,以供唤醒原语唤醒进程时用。仅当进程处于就绪状态时,才可能被调度执行。
(3)处理机的现场保留区。它用于保存进程由执行状态装变为其他状态时CPU现场信息,以便当该进程再次被调度运行时恢复处理机现场信息用,以使该进程能继续正常执行。被保留的CPU现场信息,通常有程序状态字(PSW)、程序计数器的内容、通用寄存器的内容和用户栈的指针等。
(4)进程相应的程序和数据地址。这是根据内存管理方式给出的该进程相应的程序和数据所在的位置信息(如内存或外存地址等),以便把PCB与其程序和数据联系起来。
(5)进程资源清单。它列出了进程所拥有的除了CPU之外的资源记录,例如,打开的文件表、拥有的I/O设备等。
(6)进程优先级。这是一个表示进程使用处理机的优先级别的整数,是采用基于优先级的进程调度算法的系统在进行进程调度时的主要依据。
(7)进程同步与通信机制。这是用于实现进程间互斥、同步和通信所需的信号量、信箱、和消息队列的指针等。
(8)进程所在PCB的链接字。许多操作系统根据进程的状态,把相应的PCB加入到不同的队列中。这样PCB就有个链接字,指出该进程所在队列中的下一个进程PCB的首地址。当该进程是所在队列的最后一个PCB时,其链接字的值为空。
(9)与进程有关的其他信息。这些信息主要有进程的家族信息(如该进程的父、子进程的PCB指针等)、进程的记账信息、进程占用CPU的时间、进程所属的用户等。
4. 进程的基本状态及状态的转换
一、基本状态
(1)就绪状态
当进程已分配到除CPU意外的所有必要资源,只要获得处理机,便可立即执行,这是的进程状态成为就绪状态。在一个系统中,可以有多个进程同时处于就绪状态。
(2)执行状态
当进程已获得处理机,其程序正在处理机上执行,这是的进程状态成为执行状态。在单处理机系统中,只有一个进程处于执行状态。而在多处理机系统中,可能有多个进程同时处于执行状态。
(3)阻塞状态
正在执行的进程,由于等待某件事情发生而无法继续执行时,便放弃处理机而处于暂停状态。由于进程的执行受到阻塞,故把这种状态成为阻塞状态,有时也称为等待状态。引起进程阻塞的事件可以有多种,比如请求I/O、申请缓冲区、等待某个信号或消息等。系统中同时处于阻塞状态的进程可以有多个。
二、进程三种基本状态的转换
处于就绪状态的进程,在调度程序为他分配了处理机之后,该进程便可执行,相应地,其状态就从就绪变成执行。正在执行的进程,如果因为分配给它的时间片已经用完而被暂停执行,则其状态便从执行变回就绪。如果因等待某件事情发生而是正在执行的进程受阻,无法继续执行下去,则该进程将由执行状态变为阻塞状态,即它将让出处理机并等待。处于阻塞状态的进程,若其等待的事件已经发生,则该进程将从阻塞状态变为就绪状态。

5. 进程的控制
一、进程控制机构
(1)原语操作
原语是操作系统内核中由若干条机器指令构成用于完成特定功能的一个过程,该过程在执行时是不可分割的,即呈现院子特性,他是机器指令的延伸。现代操作系统通常采用屏蔽中断的方法来保证原语在执行时的不可分割性,这种原子性对于解决进程同步和互斥问题是非常重要的。为了提高系统的效率和保证访问系统数据的正确性,内核在实现其基本功能时常采用原子操作,常见的内核原语有进程控制原语、用于链表操作的原语以及用于控制进程互斥、同步的原语。
(2)进程管理
进管管理一般都在内核中实现,这主要是因为这些功能模块的运行频率较高,例如,进程调度与分派、进程的创建、进程的撤销等,或是因为它们为多种功能模块所调用,例如,实现进程的同步和进程通信的原语等。
二、进程控制原语
进程控制原语是对进程生命周期控制和实现进程状态转换的原语,主要包括进程的创建与撤销、阻塞与唤醒、挂起与激活六个原语。下面仅介绍涉及进程三种基本状态及其转换的前四个原语。
(1)进程创建原语
一个进程可以调用进程创建原语来创建一个子进程。进程创建原语的主要操作步骤为:
①申请空闲的PCB,为新进程获得其内部标识;
②为新进程分配内存空间等资源;
③初始化PCB的内容,例如,该进程的内部表示、状态(常设为就绪)、优先级、程序地址、父进程PCB指指针等;
④将新进程插入到PCB的就绪队列。
(2)进程撤销原语
一个进程在完成任务正常结束或因某些错误和故障被迫结束时,应由其父进程调用进程撤销原语来予以撤销,以便及时释放其所占有的各类资源。其进程车撤销原语在撤销指定进程的同时,也应撤销其所有的子孙进程。进程撤销原语的主要操作步骤为:
①根据被撤销进程的标识符从PCB表中检索出该进程的PCB,从中读出该进程的状态;
②若该进程正处于执行状态,则应立即终止它的执行,并置重新调度标志位逻辑真值(该标志初值为逻辑假);
③若该进程的状态不是执行态,则把该进程的PCB从相应的队列中移去;
④若该进程还有子孙进程,则递归撤销其所有子孙进程;
⑤撤销时,把属于父进程的资源归还给父进程,把属于自己的申请的资源归还给系统,注销其资源描述清单,最后释放该进程的PCB;
⑥若重新调度标志为真,则转进程调度程序。
(3)进程阻塞原语
当进程请求某件事件尚未出现时,该进程调用进程阻塞原语,放弃处理机,使自己从执行状态变为阻塞状态。进程阻塞原语的主要操作步骤为:
①终止调用者进程自身的执行;
②设置调用者进程自己的状态为阻塞状态;
③把调用者进程的PCB插入到相应的阻塞队列;
④转进程调度程序。
(4)进程唤醒原语
执行的进程释放某资源后,调用进程唤醒原语将因等待该资源而阻塞的一个进程唤醒成就绪。进程唤醒原语的主要操作步骤为:
①找出被唤醒进程的内部标识;
②把该进程从相应的阻塞队列中移出;
③重新设置该进程的状态为就绪;
④将该进程插入到PCB的就绪队列。
6. 进程控制模拟实现提高实验
浏览代码可以发现,进程创建和撤销我们已经实现,现在需要是实现的是阻塞进程以及唤醒进程的操作,因此我们添加了stop()函数和wake()函数分别实现这两种功能。找到定义队列的语句,还需要注意的是,现在我们有两种进程队列,一种是就绪进程队列,另一种是阻塞进程队列。
PCB *ready = NOTHING, *pfend = NOTHING,*p =NOTHING,*stop = NOTHING,*stopend = NOTHING;
其中,ready和pfend分别表示就绪进程队列的队首和队尾,stop和stopend分别表示阻塞进程队列的队首和队尾。当我们键入回车,则检查就绪队列和阻塞队列是否均为空,如果不是,则执行就绪队列队首进程或是等待;当我们键入字符‘s’,则阻塞就绪队列队首进程,将其添加到阻塞队列队尾;当我们键入字符‘w’,则唤醒阻塞队列队首进程,将其添加到就绪队列队尾。如此往复,直至所有进程执行完毕程序停止。
| 思考: 为了简化程序,我们默认总是唤醒或阻塞队首进程,如果想要阻塞或唤醒指定进程,该如何实现? |
你可以看到,创建进程和销毁进程已经实现,现在需要你补全阻塞进程block()函数和wake()函数的功能。
一、创建并插入进程
浏览代码,找到fcfs()函数,我们将新的进程插入其应在的就绪队列,至此,进程创建完成。
1 void fcfs()//插入进程
2 {
3 if(!ready ){
4 ready = p;
5 pfend = p;
6 }
7 else{
8 p->link = pfend->link;
9 pfend->link = p;
10 pfend = p;
11 }
12 }
二、销毁进程
查看destroy()函数,进程运行完成时,我们只需要释放该进程并找到下一个就绪进程。
1 void destroy()
2 {
3 printf("\n进程[%s]已完成.\n",ready->name);
4 p = ready;
5 ready = ready->link;
6 free(p);
7 }
三、阻塞进程
查看block()函数,若阻塞队列为空,则直接把该进程放在阻塞队列队首,反之则放在阻塞队列队尾。
1 void block()
2 {
3 if(!stop){
4 ready->state = 'b';
5 //待补全
6 }
7 else{
8 ready->state = 'b';
9 //待补全
10 }
11 }
四、唤醒进程
查看wake()函数,如果阻塞队列为空,则无需唤醒的进程,反之,如果就绪进程为空则将其放在队首,不为空则放在就绪队列队尾。
1 void wake()
2 {
3 if(stop == NOTHING){
4 printf("\n阻塞队列为空,请进行其他操作");
5 return;
6 }
7 else{
8 if(ready != NOTHING){
9 //待补全
10 }
11 else{
12 //待补全
13 }
14 //待补全
15 }
16 }
补全代码如下:


3951

被折叠的 条评论
为什么被折叠?



