4.进程同步与互斥

基本概念

在多道程序共同执行的条件下,进程与进程是并发执行的,不同进程之间存在不同的相互制约关系。为了协调进程之间的相互制约关系,引入进程同步的概念。

  • 进程之间存在同步互斥的制约关系

  • 临界资源的访问,必须互斥地进行

  • 同步(直接制约关系)——先后次序:为完成某种任务而建立的两个或多个进程,这些进程因为需要在某些位置上协调它们的工作次序而等待、传递消息所产生的制约关系。进程间的直接制约关系就是源于它们之间的相互合作

  • 互斥(间接制约关系)——锁定机制:某一资源同一时间只允许一个进程对其进行访问

  • 临界资源:一次仅允许一个进程使用的资源(打印机、变量、数据)

  • 临界区:访问临界资源的那段代码

同步机制应遵循的准则

  1. 空闲让进:临界区空闲时,应该允许一个请求进入临界区的进程立即进入
  2. 忙则等待:当已经有进程进入临界区,其它试图进入的进程的必须等待
  3. 有限等待:对请求访问临界区资源的进程,应保证在有限的时间内能进入自己的临界区,避免“死等”状态
  4. 让权等待:当进程不能进入临界区时,应当立即释放处理机,以免进入“忙等”状态

互斥实现方法

image

信号量的工作原理

  1. 整型信号量(不遵循让权等待原则,使进程处于忙等状态)

    wait(S){
    	while(S<=0);
    	S=S-1;
    }
    
    signal(S){
    	S=S+1;
    }
    
  2. 记录型信号量

    • value>0,有多少空位
    • value==0,刚刚满
    • value<0,有多少在等待
    typedef struct{
    	int value;
    	struct process *L; //链接等待该进程的所有资源
    }semaphore;
    
    wait(semaphore S){
    	S.value--;
    	if(S.value<0)block(S.L);
    }
    
    signal(semaphore S){
    	S.value++;
    	if(S.value<=0)wakeup(S.L);
    }
    
  3. AND型信号量

    • 将进程在整个运行过程中需要的所有资源,一次性全部地分配给进程,待进程使用完后再一起释放。只要尚有一个资源未能分配给进程,其它所有可能为之分配的资源也不分配给它。
  4. 信号量集

    • 在记录型信号量机制中,wait(S)signal(S)操作仅能对信号量施以加 1 或减 1 操作,意味着每次只能获得或释放一个单位的临界资源。而当一次需要 N 个某类临界资源时,便要进行 N 次 wait(S)操作,显然这是低效的。此外,在有些情况下,当资源数量低于某一下限值时,便不予以分配。因而,在每次分配之前,都必须测试该资源的数量,看其是否大于其下限值。基于上述两点,可以对 AND 信号量机制加以扩充,形成一般化的“信号量集”机制。

信号量的应用

  1. 信号量实现进程同步

    semaphore S=0;
    P1(){
    	P(S);
    	……
    }
    
    P2(){
    	……
    	V(S);
    }
    
  2. 信号量实现进程互斥

    semaphore S=1;
    P1(){
        P(S);
        ……
        V(S);
    }
    
    P2(){
        P(S);
        ……
        V(S);
    }
    
  3. 信号量实现前驱关系

    image
    semaphore a=0,b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;
    p1(){ S1; signal(a); signal(b); }
    p2(){ wait(a); S2; signal(c); signal(d); }
    p3(){ wait(b); S3; signal(e); signal(f); } 
    p4(){ wait(c); S4; signal(g); }
    p5(){ wait(d); S5; signal(h); }
    p6(){ wait(e); S6; signal(i); }
    p7(){ wait(f); S7; signal(j); }
    p8(){ wait(g); wait(h); wait(i); wait(j); S8;}
    

管程

  • 一个管程定义了一个数据结构和能被并发进程执行(在该数据结构上)的一组操作,这组操作能同步进程和改变管程中的数据。

管程由四部分组成:

  1. 管程的名称

  2. 局部于管程内部的共享数据结构说明

  3. 对该数据结构进行操作的一组过程

  4. 对局部于管程内部的共享数据设置初始值的语句

posted @ 2023-12-20 16:39  风雨zzm  阅读(29)  评论(0编辑  收藏  举报