【操作系统期末复习】 第四章 进程同步

目录

4.1 进程同步的概念

4.2 软件同步机制

4.3 硬件同步机制

4.4 信号量机制

 信号量的应用

4.5 管程机制

4.6 经典进程的同步问题

        4.6.1 生产者—消费者问题

        4.6.2 哲学家进餐问题

        4.6.3 读者——写者问题

        4.6.7 关于信号量的讨论

4.7 Linux进程同步机制


4.1 进程同步的概念

        1.主要任务

        使并发执行的诸进程之间能有效地共享资源和相互合作,从而使程序的执行具有可再现性。

进程间的制约关系。

        间接相互制约关系(互斥关系) 进程互斥使用临界资源

        直接相互制约关系(同步关系)进程间相互合作

        临界资源

       系统中某些资源一次只允许一个进程使用,称这样的资源为临界资源或互斥资源或共享变量。

        临界资源可能是硬件,也可能是软件:变量,数据,表格,队列等

临界区: 进程中涉及临界资源的代码段
进入区: 用于检查是否可以进入临界区的代码段。
退出区: 将临界区正被访问的标志恢复为未被访问标志。
剩余区: 其他代码

访问临界资源的循环进程描述如下:

 while(TRUE)

{     ENTRY   SECTION   //进入区

        CRITICAL   SECTION   //临界区

        EXIT   SECTION  //退出区

        REMAINDER   SECTION //剩余区

        }

        互斥的实质就是同步,或者说,互斥是同步的一种特殊形式。

        2.同步机制应遵循的原则

        (1)  空闲让进:当无进程处于临界区,应允许一个请求进入临界区的进程立即进入自己的临界区;

        (2)  忙则等待:已有进程处于其临界区,其它试图进入临界区的进程必须等待;

        (3)  有限等待:等待进入临界区的进程不能"死等"

        (4)  让权等待:不能进入临界区的进程,应释放CPU(如转换到阻塞状态);

        3.进程同步机制

        1)软件同步机制

        (2)硬件同步机制

        (3)信号量机制(P-V操作)

        (4)管程机制

4.2 软件同步机制

        软件同步机制-Peterson解决方案

        共享变量:

        int turn = 0;
        turn == i
; //表示 Pi 能进入临界区

        j = 1-i;

        boolean flag[2];
        flag [0] = flag [1] = false;    //初值

        flag [i] = true ; //表示Pi 准备进入临界区

        进程 Pi:

        do {

  flag [i]:= true;
  turn = j;
  while (flag [j] and turn = j) ;

  临界区

  flag [i] = false;

  剩余

                } while (1);

满足三个需求;解决了两个进程的临界区问题。

4.3 硬件同步机制

        关中断,Test-and-Set指令,Swap指令 

        缺点:不符合“让权等待”原则,浪费CPU时间;很难解决复杂的同步问题。

        Test-and-Set指令实现互斥

        boolean TestAndSet(Boolean *lock)

        {boolean old = *lock;

          *lock = TRUE;

               return old;}

        进程 Pi

        do {

           while (TestAndSet(lock)) ;

           critical section

                  lock = FALSE;

           remainder section

        }

        共享数据:

        boolean lock = FALSE;

        Swap指令实现互斥

        原子地交换两个变量

        void Swap(boolean *a, boolean *b) {

          boolean temp = *a;

          *a = *b;

          *b = temp;

           }

        进程 Pi

        do {

            key = true;

            do {

                  Swap(lock,key);

                 }while (key != false)

            临界区

            lock = false;

            剩余区

          }while(true)

        共享数据 (初始化为 false):

        boolean lock;

        boolean waiting[n];

4.4 信号量机制

       1965年,由荷兰学者迪科斯彻Dijkstra提出(PV分别代表荷兰语的Proberen (test)Verhogen (increment)),是一种卓有成效的进程同步机制。

        信号量-软件解决方案:

  • 保证两个或多个代码段不被并发调用
  • 在进入关键代码段前,进程必须获取一个信号量,否则不能运行
  • 执行完该关键代码段,必须释放信号量
  • 信号量有值,为正说明它空闲,为负说明其忙碌

        类型:整型信号量、记录型信号量、AND信号量、信号量集

        1. 整型信号量:

  • 信号量S-整型变量
  • 提供两个不可分割的[原子操作]访问信号量

        wait和signal操作可描述为:

        wait(S)

                 {  while(S≤0);      /*do  no-op*/

                    S--;         }

        signal(S):

                 {  S++;  }        

Wait(s) 又称为 P(S)
Signal(s) 又称为 V(S)
缺点: 进程忙等, 没能做到“让权等待”。
 
2.  记录型信号量: 去除忙等的信号量
          基本思想:

 1、设置一个代表资源数目的整型变量S.value(资源信号量)

 2、设置一链表L用于链接所有等待的进程,进程等待队列S.list

信号量只能通过 初始化 两个标准的原语PV 来访问--作为 OS 核心代码执行, 不受进程调度的打断
初始化 指定一个非负整数值,表示 空闲资源总数 (又称为 " 资源信号量 " )--若为非负值表示 当前的空闲资源数 ,若为负值其绝对值表示 当前等待临界区的进程数
记录型信号量采用了记录型的数据结构,描述为:

typedef struct{

                        int value;

                        struct process_control_block *list;

                       }semaphore;      

wait signal 操作(即PV操作)可描述为:

wait(semaphores *S) {     //请求一个单位的资源

    S->value --;   //资源减少一个

    if (S->value<0) block(S->list)   //进程自我阻塞

}

S.value0 时,进程会立即将自己阻塞,因此解决了整型信号量的“忙等”问题,做到了“让权等待”。

signal(semaphores *S)   //释放一个单位资源

{

    S->value++;   //资源增加一个

    if (S->value<=0) wakeup(S->list);   //唤醒等待队列中的一个进程

} 

3.AND型信号量

  • AND型信号量同步的基本思想:将进程在整个运行过程中需要的所有资源,一次性全部分配给进程,待进程使用完后再一起释放。
  • 对若干个临界资源的分配,采用原子操作。
  • wait(S)操作中增加了一个“AND”条件,故称之为AND同步,或同时wait(S)操作,即Swait(Simultaneous wait)

Swait(S1S2,…,Sn)  {

     while (TRUE)  {

   if (Si>=1 && && Sn>=1) {

             for (i =1;i<=n;i++) Si--;

    break;

             }

   else  {

   place the process in the waiting queue associated with the first Si found with Si<1and set the program count of this process to the beginning of Swait operation

   }

      }

}

        

Ssignal(S1S2Sn)  {

      while (TRUE) {

      for (i=1 ; i<=n;i++) {

             Si++

   Remove all the process waiting in the queue associated with Si into the ready queue.

       }

       }

}

        4.信号量集

        在记录型信号量中,waitsignal仅能对某类临界资源进行一个单位的申请和释放,当需要对N个单位进行操作时,需要Nwait/signal操作,效率低下

        扩充AND信号量:对进程所申请的所有资源以及每类资源不同的资源需求量,在一次PV原语操作中完成申请或释放

        进程对信号量Si的测试值是该资源的分配下限值ti,即要求Si≥ti,否则不予分配。一旦允许分配,进程对该资源的需求值为di,即表示资源占用量,进行Si= Si-di操作

Swait (S1 t1 d1 Sn tn dn )
Ssignal (S1 d1 Sn dn )

 信号量的应用

  • 利用信号量实现进程互斥
  • 利用信号量实现前趋关系
  • 利用信号量实现进程同步

1. 用信号量实现进程互斥

         必须置一次且只能置一次初值
        初值为整数,且不能为负数
        只能执行P V 操作
        
        信号量使用注意事项:
        . 对于两个并发进程,互斥信号量的值仅取 1 0 -1 三个值:
        .若mutex 1 表示没有进程进入临界区;若 mutex 0 表示有一个进程进入临界区;若 mutex -1 表示一个进程进入临界区,另一个进程等待进入。
        .当实现n 个进程并发时,互斥信号量的取值为 1 0 -1 -(n-1)

        .PV操作必须成对出现:遗漏P(mutex)将不能保证互斥访问,遗漏V(mutex)将不能再使用临界资源之后将其释放(给其他等待的进程)

        ..mutex用于实现互斥,初值为1。

        
         2. 利用信号量描述前趋关系
  • 在进程P1中,用S1signal(S)
  • 在进程P2中,用wait(S)S2

main(){

   Semaphore a,b,c,d,e,f,g;

    a.value=0;b.value=0;c.value=0;

    d.value=0;e.value=0;f.value=0;g.value=0;

  cobegin

  { S1;signal(a);signal(b); }

  { wait(a);S2;signal(c) ;signal(d);}

  { wait(b);S3;signal(e); }

  { wait(c);S4;signal(f); }

  { wait(d);S5;signal(g); }

  { wait(e);wait(f);wait(g);S6; }

  corend

}

        3.利用信号量实现进程同步

实现各种同步问题
例子: P1 P2 需要代码段 C1 C2 先运行

    semaphores s=0; //主要用于传递消息

4.5 管程机制

        1.为什么引入管程?

        需要程序员实现,编程困难
        维护困难
       

        2.管程的定义:

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

        3.管程的语法:

Monitor monitor_name  {         /*管程名*/

share variable declarations /*共享变量说明*/

cond declarations             /*条件变量说明*/

public:                         /*能被进程调用的过程*/

void P1(……) {……/*对数据结构操作的过程*/

void P2(……) {……}

……

void (……) {……}

……

{                              /*管程主体*/      

initialization code;       /*初始化代码*/

……     

}

         4.管程功能

          互斥

           管程中的变量只能被管程中的操作访问
          任何时候只有一个进程在管程中操作
          类似临界区

          由编译器完成

           同步

           条件变量
           唤醒和阻塞操作
                
            5.条件变量问题
                
             管程内可能存在不止1个进程。

            例如:进程P调用signal操作唤醒进程Q

             存在的可能 处理方式
 P等待 ,直到 Q 离开管程或等待另一条件( Hoare
  Q等待 ,直到 P 离开管程或等待另一条件( Hansen

4.6 经典进程的同步问题

        4.6.1 生产者—消费者问题

        只要仓库未满,生产者就可以把产品放入仓库。只要仓库未空,消费者就可以从仓库中取走物品

生产者(M个):生产产品,并放入缓冲区
消费者(N个):从缓冲区取产品消费
问题:如何实现生产者和消费者之间的同步和互斥?
  速成这部分大题

        4.6.2 哲学家进餐问题

        4.6.3 读者——写者问题

        4.6.7 关于信号量的讨论

                信号量的使用:

                信号量必须置一次且只能置一次初值,初值不能为负数

                除了初始化,只能通过执行P、V操作来访问信号量

                使用中存在的问题:

                死锁

                饥饿

                死锁 :两个或多个进程无限期地等待一个事件的发生,而该事件正是由其中的一个等待进程引起的

        例如:SQ是两个初值为1的信号量

                    P0                          P1

                    P(S);                     P(Q);

                    P(Q);                     P(S);

                      M                  ​​​​​​​        M

                    V(S);                      V(Q);

                    V(Q)                       V(S);

                饥饿 :无限期地阻塞,进程可能永远无法从它等待的信号量队列中移去(只涉及一个进程)。

        信号量的物理含义:

Ø S>0 表示有 S 个资源可用;
Ø S=0 表示无资源可用;
Ø S<0 | S | 表示 S 等待队列中的进程个数。
Ø P(S): 表示申请一个资源 ;
Ø V(S) 表示释放一个资源。信号量的初值应该大于等于 0
PV操作的使用:
P.V 操作必须成对出现,有一个 P 操作就一定有一个 V 操作
当为互斥操作时,它们同处于同一进程
当为同步操作时,则不在同一进程中出现
如果 P(S1) P(S2) 两个操作在一起,那么 P 操作的顺序至关重要 , 一个同步 P 操作与一个互斥 P 操作在一起时同步 P 操作在互斥 P 操作前
而两个 V 操作 无关紧要

        信号量同步的缺点:

Ø同步操作分散: 信号量机制中,同步操作分散在各个进程中,使用不当就可能导致各进程死锁(如 P V 操作的次序错误、重复或遗漏)
Ø易读性差: 要了解对于一组共享变量及信号量的操作是否正确,必须通读整个系统或者并发程序;
Ø不利于修改和维护: 各模块的独立性差,任一组变量或一段代码的修改都可能影响全局;
Ø正确性难以保证: 操作系统或并发程序通常很大,很难保证这样一个复杂的系统没有逻辑错误。

4.7 Linux进程同步机制

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值