操作系统--信号量的机制与应用

资源互斥访问图例

操作系统--信号量的机制与应用_第1张图片

同步机制应遵循的准则

     (1)空闲让进     当无进程处于临界区时,应允许一个请求进入临界区的进程进入临界区;
     (2)忙则等待     当已有进程进入临界区时,其他试图进入临界区的进程必须等待;
    (3)有限等待     对要求访问临界资源的进程,应保证在有限时间内能进入自己的临界区,以免陷入“死等”状态;

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

信号量机制

    (1)整型信号量

            思想:定义一个整型变量S,除初始化外,仅能通过两个标准的原子操作wait(S)signal(S)来访问。

wait(S): {while S≤0;    /*do no-op*/
                 S--;
               }
signal(S): {
                    S++;
                  }

理解:wait过程中,如果不满足则一直在询问,直到满足了才跳出循环,执行后续操作。执行过程中不可中断。不满足中“让权等待”规则

(2)记录型信号量

思想:用整型变量value代表资源的数目。用进程链表L来链接等待访问临界资源的进程

记录型信号量的定义:
  typedef struct {
                     int value;
                      struct process_control_block *list;
                           }semphore;
wait(semaphare *S)
  {
    S->value--;
    if (S->value<0)  block(S->list);
   }
signal(semphore *S)
 {
     S->value++;
     if (S->value≤0) then wakeup(S->list);
  }

注意:block  wakeup 阻塞与唤醒原语

理解:将访问该资源的进程放进等待列表中,使用block原语主动放弃处理机的使用权,当有进程释放资源时,使用wakeup原语将列表中第一个等待的进程唤醒。

(3)AND型信号量

        思想:将进程在整个运行过程中需要的所有资源,一次性全部地分配给进程,待进程使用完成后再一起释放。只要尚有一个资源未能分配给进程,其他所有可能为之分配的资源,也不分配给它。亦即,对若干个临界资源的分配,采取原子操作方式:要么全部分配给进程,要么一个也不分配。

AND型信号量的P、V操作
Swait(S1,S2,…,Sn)
{   while (TRUE)  
    { 
    if (S1≥1&&… &&Sn≥1){
     for (i=1;i<=n;i++)  Si--;
     break;
      }
else {将进程放入第一个Si

(4)信号量集

思想:若进程一次需要申请多类临界资源,则在进行临界资源分配时,先测试各类临界资源是否大于其下限值。若低于下限值,则不予分配。

信号量集的P、V操作
Swait(S1,t1,d1,…,Sn,tn,dn)
   while (TRUE){
 if (S1≥t1 && … && Sn≥tn )
        for (i=1;i<=n;i++)   Si:=Si-di;
        break;
}         
else { Place the executing process in the waiting queue of the first Si with Si
四种信号量的比较
   (1) 整型信号量:不满足“让权等待”
     (2)记录型信号量:只可申请一类资源,该资源有n个,一次只可申请一个。将资源分光,多类资源时易产生死锁。
     (3)AND型信号量:可申请n类资源,每类资源有m个,每次可申请每类资源中的一个。会将资源分光。

    (4)信号量集:可申请n类资源,每类资源有m个,每次可申请每类资源中的多个。但低于下限时,不予分配


利用信号量实现前趋关系

    方法:

        (1)前趋图有几条边则初始几个信号量

        (2)如果有边到达结点,则wait()

        (3)如果有边从结点出发则signal()


事例:

操作系统--信号量的机制与应用_第2张图片

P1() {S1;signal(a);signal(b);}
P2(){wait(a);S2;signal(c);signal(d);}
p3(){wait(c);S3;signal(e);}
P4(){wait(d);S4;signal(f);}
P5(){wait(b);S5;signal(g); }
P6(){wait(e);wait(f);wait(g);S6;}
Main(){
Semaphore a,b,c,d,e,f,g;
a.value=b.value=c.value=0;
d.value=e.value=0;
f.value=g.value=0;
 cobegin
P1();p2();p3();p4();p5();p6();
coend}

进程同步问题

    (1)生产者与消费者问题

                      

Int in=0;out=0;
Item buffer[n];
Semaphore mutex=1,empty=n,full=0;
void   procedure() {
               do{
      produce an item in nextp;
                           …
                           wait(empty);
                            wait(mutex);
                            buffer(in)=nextp;
                            in=(in+1%n;
                            signal(mutex);
                            signal(full);

   }while(TRUE);
}
Void consumer(){
               do{ 
                         wait(full);
                          wait(mutex);
                          nextc=buffer(out);
                          out=(out+1)%n;
                           signal(mutex);
                           signal(empty);
            consumer the item in nextc;
…
    }while (TRUE);
}

Void main() {
Cobegin 
     procedure();consumer();
   coend;
  }
    

理解:

    (1)生产者:

            (1)查看产品是否满,满了则等待消费者来拿不生产,不满继续判断

            (2)看看是否有人在,有人在则不生产,等待出来

            (3)生产过程

            (4)退出操作室

             (5)通知可以进来取商品了

    (2)消费者

            (1)查看产品是否为空  ,空了则等待生产者来生产。不为空则继续判断

            (2)查看是否有人在,有人在则不取产品,等待出来

            (3)取产品过程

            (4)退出操作室

            (5)通知可以进来生产了

    (3)互斥信号量的PV操作在同一段程序中,资源信号量的PV操作分别处于不同程序

    (4)资源信号量与互斥信号量wait的顺序不能更改

                若更改,可能引发进程死锁

                更改后分析过程:

               生产者

                        (1)判断是否有人在,没人进去

                        (2)判断是否满,满了,等待消费者来拿

                消费者

                        (1)判断是否有人,---  有人 --- 等待

    生产者不出去消费者没法进来,消费者不拿走产品,生产者无法生产,无法生产无法出去,无法出去消费者无法进来。

                                        死锁



你可能感兴趣的:(操作系统)