进程同步

引入进程后,虽然使系统中的多道程序并发执行,有效地改善资源利用率,显著地提高系统的吞吐量,但却使系统变得更加复杂。如果不能采取有效的措施(同步),对并发进程的运行进行管理,将对系统资源的无序争夺给系统造成混乱,使并发处理的结果存在着不确定性。

进程同步的基本概念
  
1. 两种形式的制约关系
  1) 间接相互制约关系
  
2) 直接相互制约关系
  
2. 临界资源(Critical Resouce)
  许多硬件资源如打印机、 磁带机等,都属于临界资源,诸进程间应采取互斥方式,实现对这种资源的共享。

问题描述:有一群生产者进程在生产产品,并将这些产品提供给消费者进程去消费。为使生产者进程与消费者进程能并发执行,在两者之间设置了一个具有 n 个缓冲区的缓冲池,生产者进程将它所生产的产品放入一个缓冲区中;消费者进程可从一个缓冲区中取走产品去消费。不允许消费者进程到一个空缓冲区去取产品,也不允许生产者进程向一个已装满产品且尚未被取走的缓冲区中投放产品。

      
 共享变量Var n, integer;  type item=…;
                            var
buffer: array[0,1,…,n-1] of item;
                          
 in, out: 0,1,…,n-1; counter: 0,1,…,n;
       
局部变量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:=counter+1;
      register1:=counter;                                            (1)
      register1:=register1+1;                                      (2)
      counter:=register1;                                            (3)

counter:=counter-1;
       register2:=counter;                                           (a)
       register2:=register2-1;                                      (b)
       counter:=register2;                                           (c)

counter:=3 执行顺序 1->2->a->b->3->c 执行结果 counter值为2
counter:=3 执行顺序 a->b->1->2->c->3 执行结果 counter值为4
3. 临界区(critical section)
  由前所述可知,多个进程必须互斥地访问计算机中的临界资源。人们把在每个进程中访问临界资源的那段代码称为临界区(critical section)
      repeat
      
     entry section
            critical section;
            exit section
            remainder section;
      until false;

4. 同步机制应遵循的规则
  用来实现互斥的同步机制必须遵循下述四条准则:
  
(1) 空闲让进
  
(2) 忙则等待
  
(3) 有限等待
  
(4) 让权等待

硬件同步机制
  虽然可以利用软件方法解决诸进程互斥进入临界区的问题,但有一定难度,并且存在很大的局限性,因而现在已很少采用。相应地,目前许多计算机已提供了一些特殊的硬件指令,允许对一个字中的内容进行检测和修正,或者是对两个字的内容进行交换等。可利用这些特殊的指令来解决临界区问题。
1. 关中断  
2. 利用Test-and-Set指令实现互斥
3. 利用Swap指令实现进程互斥

信号量机制                                           
  
1. 整型信号量                                         
  最初由Dijkstra把整型信号量定义为一个用于表示资源数目的整型量S,它与一般整型量不同,除初始化外,仅能通过两个标准的原子操作(Atomic Operation) wait(S)signal(S)访问。                                                                                 
                                                                         
      
wait(S):   while   S<=0 do no-op;                                              
                          S:=S-1;                                                                                        
      
signal(S):S:=S+1; 

        2. 记录型信号量
  
记录型信号量机制则是一种不存在“忙等”现象的进程同步机制。但在采取了“让权等待”的策略后,又会出现多个进程等待访问同一临界资源的情况。为此,在信号量机制中,除了需要一个用于代表资源数目的整型变量value外,还应增加一个进程链表指针L,用于链接上述的所有等待进程。
procedure
wait(S)                        procedure signal(S)
 var S:semaphore;                      var S: semaphore;
 begin                                            begin
  
S.value:=S.value-1;                      S.value:=S.value+1;
   if S.value<0 then block(S.L);      if S.value<=0 then wakeup(S.L);
 end                                               end                                                                     
        3. AND型信号量
  将进程在整个运行过程中需要的所有资源,采取原子操作方式,一次性全部分配给,待进程使用完后再一起释放。
  Swait(S1,S2,,Sn)
     if S1>=1 and … and Sn>=1 then for i:=1 to n do Si:=Si-1;
       endfor else
       进程进入第一个不满足的资源阻塞队列;
     endif
  Ssignal(S1,S2,…,Sn)
     for i:=1 to n do  Si:=Si+1;      //循环释放资源Si//
      检查资源Si等待队列中的所有进程,如果通过Swait测试,
      插入到就绪队列;否则插入到某个等待队列;
     endfor;

记录型信号量的问题:当一次需要 N 个某类临界资源时,便要进行 N 次 wait(S)操作,显然这是低效的。                                                                  
  Swait(S1,t1,d1,…,Sn,tn,dn)
     if S1>=t1and … and Sn>=tn then for i:=1 to n do Si:=Si-di;
       endfor else
       进程进入第一个不满足Si>=ti 的资源阻塞队列;
     endif
  Ssignal(S1,d1,…,Sn,dn)
     for i:=1 to n do  Si:=Si+di;      //循环释放资源Si//
      检查资源Si等待队列中的所有进程,如果通过Swait测试,
      插入到就绪队列;否则插入到某个等待队列;
     endfor;
 关于“信号量集”,我们一般讨论的是如下几种特殊情况:
(1)
Swait(S,d,d)
       信号量集中只有一个信号量 S,允许它每次申请 d 个资源,当现有资源数少于 d 时,不予分配。
(2)
Swait(S,1,1)
       此时的信号量集已蜕化为一般的记录型信号量(S>1 时)或
互斥信号量(S=1 时)。
(3)
Swait(S,1,0)
       这是一种很
特殊且很有用的信号量操作。当 S≥1 时,允许多个进程进入某特定区;当 S 变为 0 后,将阻止任何进程进入特定区。换言之,它相当于一个可控开关

信号量的应用
  
1. 利用信号量实现进程互斥方法
  设置一互斥信号量mutex,并设其初始值为1,然后将各进程访问该资源的临界区CS置于wait(mutex)signal(mutex)操作之间即可。

进程互斥代码描述
Var
mutex: semaphore:=1
    begin
    parbegin
       process 1: begin                             
process 2: begin
            repeat                                                repeat
           wait(mutex);                                      wait(mutex);
           critical section                                   critical section
           signal(mutex);                                   signal(mutex);
           remainder seetion                              remainder section
           until false;                                         until false;
           end                                                    end
                                                                 parend

2. 利用信号量实现前趋关系
  还可利用信号量来描述程序或语句之间的前趋关系。设有两个并发执行的进程P1P2P1中有语句S1P2中有语句S2。我们希望在S1执行后再执行S2

前驱关系的实现
        1. 置一个初值为 0 的公用信号量 S
  2. 在进程P1中:S1; signal(S);
  3. 在进程P2中:wait(S); S2;

前趋图的代码描述:
Var a,b,c,d,e,f,g:semaphore: =0,0,0,0,0,0,0;
begin
    parbegin
      begin S1; signal(a); signal(b); end;
      begin wait(a); S2; signal(c); signal(d); end;
      begin wait(b); S3; signal(e); end;
      begin wait(c); S4; signal(f); end;
      begin wait(d); S5; signal(g); end;
      begin wait(e); wait(f); wait(g); S6; end;
    parend
end

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值