进程管理(一)

操作系统前言摘录


1.进程的基本概念
2.进程同步



进程的基本概念


程序顺序执行时的特征:

(1) 顺序性:处理机的操作严格按照程序所规定的顺序执行,即每一操作必须在上一个操作结束之后开始。

(2) 封闭性:程序是在封闭的环境下执行的,即程序运行时独占全机资源,资源的状态(除初始状态外)只有本程序才能改变它。程序一旦开始执行,其执行结果不受外界因素影响。

(3) 可再现性:只要程序执行时的环境和初始条件相同,当程序重复执行时,不论它是从头到尾不停顿地执行,还是“停停走走”地执行,都将获得相同的结果。

程序顺序执行时的特性,为程序员检测和校正程序的错误带来了很大的方便。 


程序并发执行时的特征:

并发程序:是指两道或两道以上程序同时装入内存中运行,这些程序的执行在时间上互相有重叠,即在一个程序执行结束之前,另一个程序已经开始执行。

特征:(1)间断性 (2)失去封闭性 (3)不可再现性

(1)间断性:程序在并发执行时,由于它们共享系统资源,以及为完成同一项任务而相互合作,致使在这些并发执行的程序之间,形成了相互制约的关系。简而言之,相互制约将导致并发程序具有“执行—暂停—执行”这种间断性的活动规律。 

(2)失去封闭性:程序在并发执行时,是多个程序共享系统中的各种资源,因而这些资源的状态将由多个程序来改变,致使程序的运行失去了封闭性。这样,某程序在执行时,必然会受到其它程序的影响。例如,当处理机这一资源已被某个程序占有时,另一程序必须等待。 

(3)不可再现性:程序在并发执行时,由于失去了封闭性,也将导致其再失去可再现性。例如,有两个循环程序A和B,它们共享一个变量N。程序A每执行一次时,都要做N:=N+1操作;程序B每执行一次时,都要执行Print(N)操作,然后再将N置成“0”。程序A和B以不同的速度运行。这样,可能出现下述三种情况(假定某时刻变量N的值为n)。

(1)  N:=N+1在Print(N)和N:=0之前,此时得到的N值分别为n+1,n+1,0。
(2)  N:=N+1在Print(N)和N:=0之后,此时得到的N值分别为n,0,1。
(3)  N:=N+1在Print(N)和N:=0之间,此时得到的N值分别为n,n+1,0。 
上述情况说明,程序在并发执行时,由于失去了封闭性,其计算结果已与并发程序的执行速度有关,从而使程序的执行失去了可再现性,亦即,程序经过多次执行后,虽然它们执行时的环境和初始条件相同,但得到的结果却各不相同。 


进程的特征与状态

在多道程序环境下,程序的执行属于并发执行,此时它们将失去其封闭性,并具有间断性及不可再现性的特征。这决定了通常的程序是不能参与并发执行的,因为程序执行的结果是不可再现的。这样,程序的运行也就失去了意义。为使程序能并发执行,且为了对并发执行的程序加以描述和控制,人们引入了“进程”的概念。

1.进程的定义

有许多人从不同的角度对进程下过定义,其中较典型的进程定义有:
(1) 进程是程序的一次执行。
(2) 进程是一个程序及其数据在处理机上顺序执行时所发生的活动。 
(3) 进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。 

进程与程序实体:


2.进程的特征

①结构性:进程包括可执行的程序代码、程序的数据和堆栈、程序计数器、堆栈指针、有关寄存器、以及所有运行程序所必须的其它信息。

(通常的程序是不能并发执行的。为使程序(含数据)能独立运行,应为之配置一进程控制块,即PCB(Process Control Block);而由程序段、相关的数据段和PCB三部分便构成了进程实体。在早期的UNIX版本中,把这三部分总称为“进程映像”。值得指出的是,在许多情况下所说的进程,实际上是指进程实体,例如,所谓创建进程,实质上是创建进程实体中的PCB;而撤消进程,实质上是撤消进程的PCB。)

②动态性:进程是程序执行的过程。

(进程的实质是进程实体的一次执行过程,因此,动态性是进程的最基本的特征。动态性还表现在:“它由创建而产生,由调度而执行,由撤消而消亡”。可见,进程实体有一定的生命期,而程序则只是一组有序指令的集合,并存放于某种介质上,其本身并不具有运动的含义,因而是静态的。 )

③并发性:进程使程序能并发执行。

(这是指多个进程实体同存于内存中,且能在一段时间内同时运行。并发性是进程的重要特征,同时也成为OS的重要特征。引入进程的目的也正是为了使其进程实体能和其它进程实体并发执行;而程序(没有建立PCB)是不能并发执行的。)

④独立性:进程是独立运行的基本单位,也是系统资源分配与调度的独立单位。

(在传统的OS中,独立性是指进程实体是一个能独立运行、独立分配资源和独立接受调度的基本单位。凡未建立PCB的程序都不能作为一个独立的单位参与运行。)

⑤异步性:进程以各自独立的、不可预知的速度向前推进。

(这是指进程按各自独立的、 不可预知的速度向前推进,或说进程实体按异步方式运行。)

3.进程的三种基本状态

进程执行时的间断性决定了进程可能具有多种状态。事实上,运行中的进程可能具有以下三种基本状态:
1)就绪状态(Ready)

当进程已分配到除CPU以外的所有必要资源后,只要再获得CPU,便可立即执行,进程这时的状态称为就绪状态。在一个系统中处于就绪状态的进程可能有多个,通常将它们排成一个队列,称为就绪队列。 
2)执行状态(Executing)

进程已获得CPU,其程序正在执行。在单处理机系统中,只有一个进程处于执行状态; 在多处理机系统中,则有多个进程处于执行状态。
3)阻塞状态(Blocked)

正在执行的进程由于发生某事件而暂时无法继续执行时,便放弃处理机而处于暂停状态,亦即进程的执行受到阻塞,把这种暂停状态称为阻塞状态,有时也称为等待状态或封锁状态。致使进程阻塞的典型事件有:请求I/O,申请缓冲空间等。通常将这种处于阻塞状态的进程也排成一个队列。有的系统则根据阻塞原因的不同而把处于阻塞状态的进程排成多个队列。 



进程控制块

1.进程控制块的作用

为了描述和控制进程的运行,系统为每个进程定义了一个数据结构——进程控制块PCB(Process Control Block),它是进程实体的一部分,是操作系统中最重要的记录型数据结构。PCB中记录了操作系统所需的、用于描述进程的当前情况以及控制进程运行的全部信息。进程控制块的作用是使一个在多道程序环境下不能独立运行的程序(含数据),成为一个能独立运行的基本单位,一个能与其它进程并发执行的进程。

  • 在进程的生命期中,系统总是通过PCB对进程进行控制的。
  • 系统是根据进程的PCB而感知到该进程的存在的。
  • PCB是进程存在的惟一标志。

OS是根据PCB来对并发执行的进程进行控制和管理的。例如,当OS要调度某进程执行时,要从该进程的PCB中查出其现行状态及优先级;在调度到某进程后,要根据其PCB中所保存的处理机状态信息,设置该进程恢复运行的现场,并根据其PCB中的程序和数据的内存始址,找到其程序和数据; 进程在执行过程中,当需要和与之合作的进程实现同步、通信或访问文件时,也都需要访问PCB;当进程由于某种原因而暂停执行时,又须将其断点的处理机环境保存在PCB中。

  • 当系统创建一个新进程时,就为它建立了一个PCB;进程结束时又回收其PCB,进程于是也随之消亡。
  • PCB可以并且只能被操作系统中的多个模块读或修改。如被调度程序、资源分配程序、中断处理程序以及监督和分析程序等读或修改。
  • PCB应常驻内存。因为PCB经常被系统访问,尤其是被运行频率很高的进程及分派程序访问。
  • 系统将所有的PCB组织成若干个链表(或队列),存放在操作系统中专门开辟的PCB区内。例如在Linux系统中用task_struct数据结构来描述每个进程的进程控制块,在Windows操作系统中则使用一个执行体进程块(EPROCESS)来表示进程对象的基本属性。 

2.进程控制块中的信息

1)进程标识信息(进程标识符、用户名、程序名等)

进程标识符用于惟一地标识一个进程。一个进程通常有两种标识符:
(1) 内部标识符PID 。在所有的操作系统中,都为每一个进程赋予了一个惟一的数字标识符,它通常是一个进程的序号。设置内部标识符主要是为了方便系统使用。
(2) 外部标识符。它由创建者提供,通常是由字母、数字组成,往往是由用户(进程)在访问该进程时使用。为了描述进程的家族关系,还应设置父进程标识及子进程标识。此外,还可设置用户标识,以指示拥有该进程的用户。 

2)处理机状态信息

处理机状态信息主要是由处理机的各种寄存器中的内容组成的。处理机在运行时,许多信息都放在寄存器中。当处理机被中断时,所有这些信息都必须保存在PCB中,以便在该进程重新执行时,能从断点继续执行。这些寄存器包括:

① 通用寄存器:又称为用户可视寄存器。它们是用户程序可以访问的,用于暂存信息,在大多数处理机中,有 8~32个通用寄存器,在RISC结构的计算机中可超过100个;
② 指令计数器:其中存放了要访问的下一条指令的地址;
③ 程序状态字PSW:其中含有状态信息,如条件码、执行方式、中断屏蔽标志等;
④ 用户栈指针:每个用户进程都有一个或若干个与之相关的系统栈,用于存放过程和系统调用参数及调用地址,栈指针指向该栈的栈顶。 

3)进程调度信息

PCB中需存放一些与进程调度和进程对换有关的信息,包括:

① 进程状态,指明进程的当前状态,作为进程调度和对换时的依据;
② 进程优先级,用于描述进程使用处理机的优先级别的一个整数,优先级高的进程应优先获得处理机;
③ 进程调度所需的其它信息,它们与所采用的进程调度算法有关,比如,进程已等待CPU的时间总和、进程已执行的时间总和等;
④ 事件,指进程由执行状态转变为阻塞状态所等待发生的事件,即阻塞原因。

4)进程控制信息

进程控制信息包括:
① 程序和数据的地址,指进程的程序和数据所在的内存或外存地(首)址,以便再调度到该进程执行时,能从PCB中找到其程序和数据;
② 进程同步和通信机制,指实现进程同步和进程通信时必需的机制,如消息队列指针、信号量等,它们可能全部或部分地放在PCB中;
③ 资源清单,即一张列出了除CPU以外的、进程所需的全部资源及已经分配到该进程的资源的清单;
④ 链接指针,它给出了本进程(PCB)所在队列中的下一个进程的PCB的首地址。 




进程同步


进程同步的基本概念

生产者-消费者(producer-consumer)问题是一个著名的进程同步问题。它描述的是:有一群生产者进程在生产产品,并将这些产品提供给消费者进程去消费。为使生产者进程与消费者进程能并发执行,在两者之间设置了一个具有n个缓冲区的缓冲池,生产者进程将它所生产的产品放入一个缓冲区中;消费者进程可从一个缓冲区中取走产品去消费。尽管所有的生产者进程和消费者进程都是以异步方式运行的,但它们之间必须保持同步,即不允许消费者进程到一个空缓冲区去取产品,也不允许生产者进程向一个已装满产品且尚未被取走的缓冲区中投放产品。 


我们可利用一个数组来表示上述的具有n个(0,1,…,n-1)缓冲区的缓冲池。用输入指针in来指示下一个可投放产品的缓冲区,每当生产者进程生产并投放一个产品后,输入指针加1;用一个输出指针out来指示下一个可从中获取产品的缓冲区,每当消费者进程取走一个产品后,输出指针加1。由于这里的缓冲池是组织成循环缓冲的,故应把输入指针加1表示成 in:= (in+1)mod n; 输出指针加1表示成out:= (out+1) mod n。当 (in+1) mod n=out时表示缓冲池满;而in=out则表示缓冲池空。此外,还引入了一个整型变量counter,其初始值为0。每当生产者进程向缓冲池中投放一个产品后,使counter加1;反之,每当消费者进程从中取走一个产品时,使counter减1。生产者和消费者两进程共享下面的变量: 

Var n,integer;
type item=…;
var buffer: array[0,1,…,n-1] of item;
in,out: 0,1,…,n-1;
counter: 0,1,…,n; 

指针in和out初始化为1。在生产者和消费者进程的描述中,noop是一条空操作指令,while condition do no-op语句表示重复的测试条件(condication),重复测试应进行到该条件变为false(假),即到该条件不成立时为止。在生产者进程中使用一局部变量nextp,用于暂时存放每次刚生产出来的产品;而在消费者进程中,则使用一个局部变量nextc,用于存放每次要消费的产品。 

生产者算法:

producer: repeat  
produce an item in nextp;

while counter=n do no-op;

buffer[in]:=nextp;
in:=(in+1) mod n;
counter:=counter+1;
until false; 

消费者算法:

consumer: repeat

while counter=0 do no-op;
nextc:=buffer[out];
out:=(out+1) mod n;
counter:=counter-1;
consumer the item in nextc;
until false; 

虽然上面的生产者程序和消费者程序在分别看时都是正确的,而且两者在顺序执行时其结果也会是正确的,但若并发执行时就会出现差错,问题就在于这两个进程共享变量counter。生产者对它做加1操作,消费者对它做减1操作,这两个操作在用机器语言实现时, 常可用下面的形式描述:

register1:=counter;      register2:=counter;
register1:=register1+1; register2:=register2-1;
counter:=register1;      counter:=register2;

假设counter的当前值是5。如果生产者进程先执行左列的三条机器语言语句,然后消费者进程再执行右列的三条语句,则最后共享变量counter的值仍为5; 反之,如果让消费者进程先执行右列的三条语句,然后再让生产者进程执行左列的三条语句,则counter值也还是5,但是,如果按下述顺序执行: 

register1:=counter;       (register1=5)
register1:=register1+1;   (register1=6)
register2:=counter;       (register2=5)
register2:=register2-1;     (register2=4)
counter:=register1;       (counter=6)
counter:=register2;       (counter=4) 

正确的counter值应当是5,但现在是4。读者可以自己试试,倘若再将两段程序中各语句交叉执行的顺序改变,将可看到又可能得到counter=6的答案,这表明程序的执行已经失去了再现性。为了预防产生这种错误,解决此问题的关键是应把变量counter作为临界资源处理,亦即,令生产者进程和消费者进程互斥地访问变量counter。

1.并发进程之间的制约关系

在多道程序环境下,当程序并发执行时,由于资源共享和进程合作,使同处于一个系统中的诸进程之间可能存在着以下两种形式的制约关系。

(1) 间接相互制约关系。

同处于一个系统中的进程,通常都共享着某种系统资源,如共享CPU、共享I/O设备等。所谓间接相互制约即源于这种资源共享,例如,有两个进程A和B,如果在A进程提出打印请求时,系统已将惟一的一台打印机分配给了进程B,则此时进程A只能阻塞;一旦进程B将打印机释放,则A进程才能由阻塞改为就绪状态。

(2) 直接相互制约关系。

这种制约主要源于进程间的合作。例如,有一输入进程A通过单缓冲向进程B提供数据。当该缓冲空时,计算进程因不能获得所需数据而阻塞,而当进程A把数据输入缓冲区后,便将进程B唤醒;反之,当缓冲区已满时,进程A因不能再向缓冲区投放数据而阻塞,当进程B将缓冲区数据取走后便可唤醒A。

  • 间接制约(互斥):多个进程不能同时使用同一个资源。   进程<-------->资源<--------->进程
  • 直接相互制约(同步):逻辑上合作的进程,执行速度相互制约。    进程<--------->进程
  • 操作系统最重要任务之一,就是采用一种高效,可靠的机制实现进程间的同步与互斥。

2.临界资源

临界资源:一次只允许一个进程使用的资源,如打印机、公共变量等。
许多硬件资源如打印机、磁带机等,都属于临界资源(Critical Resouce),诸进程间应采取互斥方式,实现对这种资源的共享。

3.临界区(CS,Critical Section)

临界区(段):包含临界资源的程序段称为临界区。
多个进程必须互斥地对临界资源进行访问。人们把在每个进程中访问临界资源的那段代码称为临界区。显然,若能保证诸进程互斥地进入自己的临界区,便可实现诸进程对临界资源的互斥访问。为此,每个进程在进入临界区之前,应先对欲访问的临界资源进行检查,看它是否正被访问。如果此刻该临界资源未被访问,进程便可进入临界区对该资源进行访问,并设置它正被访问的标志;如果此刻该临界资源正被某进程访问,则本进程不能进入临界区。因此,必须在临界区前面增加一段用于进行上述检查的代码,把这段代码称为进入区(entry section)。相应地,在临界区后面也要加上一段称为退出区(exit section)的代码,用于将临界区正被访问的标志恢复为未被访问的标志。 

进程中除上述进入区、临界区及退出区之外的其它部分的代码,在这里都称为剩余区。这样,可把一个访问临界资源的循环进程描述如下:

repeat
   entry section
   critical section;
   exit section
   remainder section;

until false;

4.同步机制应遵循的规则(临界区调度准则)

为实现进程互斥地进入自已的临界区,可用软件方法,更多的是在系统中设置专门的同步机构来协调各进程间的运行。所有同步机制都应遵循下述四条准则:

(1) 空闲让进。当无进程处于临界区时,表明临界资源处于空闲状态,应允许一个请求进入临界区的进程立即进入自己的临界区,以有效地利用临界资源。

(2) 忙则等待。当已有进程进入临界区时,表明临界资源正在被访问,因而其它试图进入临界区的进程必须等待,以保证对临界资源的互斥访问。

(3) 有限等待。对要求访问临界资源的进程,应保证在有限时间内能进入自己的临界区,以免陷入“死等”状态。

(4) 让权等待。当进程不能进入自己的临界区时,应立即释放处理机,以免进程陷入“忙等”状态。 


信号量机制

1.整型信号量

最初由Dijkstra把整型信号量定义为一个用于表示资源数目的整型量S,它与一般整型量不同,除初始化外,仅能通过两个标准的原子操作(Atomic Operation) wait(S)和signal(S)来访问。很长时间以来,这两个操作一直被分别称为P、V操作。Wait(S)和signal(S)操作可描述为:
wait(S): while    S<=0 do no-op;
              S:=S-1;
signal(S):         S:=S+1; 

wait(S)和signal(S)是两个原子操作,因此,它们在执行时是不可中断的。亦即,当一个进程在修改某信号量时,没有其他进程可同时对该信号量进行修改。此外,在wait操作中,对S值的测试和做S:=S-1操作时都不可中断。 

2.记录型信号量

在整型信号量机制中的wait操作,只要是信号量S≤0,就会不断地测试。因此,该机制并未遵循“让权等待”的准则,而是使进程处于“忙等”的状态。记录型信号量机制则是一种不存在“忙等”现象的进程同步机制。但在采取了“让权等待”的策略后,又会出现多个进程等待访问同一临界资源的情况。为此,在信号量机制中,除了需要一个用于代表资源数目的整型变量value外,还应增加一个进程链表指针L,用于链接上述的所有等待进程。记录型信号量是由于它采用了记录型的数据结构而得名的。它所包含的上述两个数据项可描述为: 

type semaphore=record
       value: integer;
       L: list of process;
       end 

信号量:

  • 有一个整型变量;
  • 有一个相关的等待队列;
  • 除了初始化外,只能对其做wait,signal 操作(P、V操作)

相应地,wait(S)和signal(S)操作可描述为:
           procedure wait(S)
     var S:semaphore;
     begin
      S.value:=S.value-1;
      if S.value<0 then block(S.L);
           end 
            procedure signal(S)
     var S: semaphore;
     begin
      S.value:=S.value+1;
      if S.value<=0 then wakeuwait(S.L);
           end 

  • S.value的初值表示系统中某类资源的数目,因而又称为资源信号量。对它的每次wait操作,意味着进程请求一个单位的该类资源,使系统中可供分配的该类资源数减少一个,因此描述为S.value:=S.value-1;当S.value<0时,表示该类资源已分配完毕,因此进程应调用block原语,进行自我阻塞,放弃处理机,并插入到信号量链表S.L中。可见,该机制遵循了“让权等待”准则。此时S.value的绝对值表示在该信号量链表中已阻塞进程的数目。
  • 对信号量的每次signal操作,表示执行进程释放一个单位资源,使系统中可供分配的该类资源数增加一个,故S.value:=S.value+1操作表示资源数目加1。若加1后仍是S.value≤0,则表示在该信号量链表中,仍有等待该资源的进程被阻塞,故还应调用wakeup原语,将S.L链表中的第一个等待进程唤醒。
  •  如果S.value的初值为1,表示只允许一个进程访问临界资源,此时的信号量转化为互斥信号量,用于进程互斥。 
(1)利用记录式信号量实现进程互斥

为使多个进程能互斥地访问某临界资源,只须为该资源设置一互斥信号量mutex,并设其初始值为1,然后将各进程访问该资源的临界区CS置于wait(mutex)和signal(mutex)操作之间即可。这样,每个欲访问该临界资源的进程在进入临界区之前,都要先对mutex执行wait操作,若该资源此刻未被访问,本次wait操作必然成功,进程便可进入自己的临界区,这时若再有其他进程也欲进入自己的临界区,此时由于对mutex执行wait操作定会失败,因而该进程阻塞,从而保证了该临界资源能被互斥地访问。当访问临界资源的进程退出临界区后,又应对mutex执行signal操作,以便释放该临界资源。利用信号量实现进程互斥的进程可描述如下: 

Var mutex: semaphore:=1;
  begin
  parbegin
    process 1: begin
            repeat
             
wait(mutex);
             critical section
             signal(mutex);
             remainder seetion
            until false;
          end 

                process 2: begin
                     repeat
                   wait(mutex);
                   critical section
                   signal(mutex);
                   remainder section
                  until false;
             end
  parend 


(2) 用记录式信号量实现同步模型

为进程设置一个同步信号量S,其初值为0;在进程需要同步的地方分别插入wait(S)和signal(S)原语。一个进程使用P原语时,则另一进程往往使用V原语与之对应,具体怎么使用要看实际情况来定。
例如,有两个进程P1、P2,P1的功能是计算x=a+b的值,a和b是常量,在P1的前面代码中能得到;P2的功能是计算y=x+1的值。 

 P1               P2
 …                …

X=a+b;        wait(S)
signal(S)    Y=X+1;
 …                …



3.AND型信号量
4.信号量集


管程机制



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值