进程同步与互斥

首先,我们看一个例子:进程P1、P2公用一个变量COUNT,初始值为0
在这里插入图片描述
在这里插入图片描述
P1、P2两个进程的执行顺序是随机的,P1、P2可能顺序执行或交错执行。
由图可见,不同的执行顺序,COUNT值会不同,这是不允许的。
在多道程序系统中,由于资源共享或进程合作,使进程间形成间接相互制约和直接相互制约关系,这需要用进程互斥与同步机制来协调两种制约关系。
(进程互斥:指在多道程序环境下,每次只允许一个进程对临界资源进行访问。进程同步:指多个相关进程在执行次序上的协调。)
临界区: 每个进程中访问临界资源的那段代码。
临界资源:在一段时间内只允许一个进程访问的资源。
虽然在多道程序系统中的诸进程可以共享各类资源,然而临界资源却是一次只能供一个进程使用,使用完后归还系统,才能给其他进程使用。(如上例变量COUNT是临界资源)。
进程对临界资源必须互斥使用,为实现对临界资源的互斥访问,应保证诸进程互斥地进入自己的临界区。为此,每个进程在进入其临界区前,必须先申请,经允许后方能进入。

同步机制应遵循的准则:

在这里插入图片描述

解决互斥的锁机制:

实现互斥的一种软件方法是采用锁机制,即提供一对上锁(Lock)和开锁(UnLock)原语,以及一个锁变量W。 进程进入临界区前,通过锁变量来判断临界资源是否被占用。

信号量机制

信号量机制是一种卓有成效的进程同步工具,被广泛应用于单处理机和多处理机系统,以及计算机网络中。
锁机制仅能表示“开”与“关”两种状态;开、关原语必须作为原子操作来进行;关锁原语中反复测试W状态,浪费了处理机的时间;锁机制只能解决互斥,不能用于同步。信号量同步机制能完满地解决上述问题,以下介绍经典信号量机制。

信号量和P、V操作

荷兰的著名计算机科学家Dijkstra把互斥的关键含义抽象成信号量(semaphore)概念,并引入在信号量上的P、V操作作为同步原语(P和V分别是荷兰文的“等待”和“发信号”两词的首字母)。信号量是个被保护的量,只有P、V操作和信号量初始化操作才能访问和改变它的值。
Dijkstra把信号量s定义为一个非负整型量。把信号量s上的P操作P(s)定义为:若s>0,则s值减1,否则执行进程等待,直到其他进程对s进行V操作。把信号量s上的V操作V(s)定义为:s值加1,若有进程在s上等待,则唤醒其中一个进程。
信号量和P、V操作原语可构成“阻塞-唤醒”同步机构:当一个进程对值为0的信号量执行P操作时便被阻塞以等待某个事件的出现;在另一进程检测到该事件发生时,通过执行V操作唤醒被阻塞的进程。在实现该同步机构时,可采取“忙等待”方式也可采取“让权等待”方式。在忙等待方式下,被阻塞进程在不主动放弃处理机的情况下忙碌等待着其他进程来唤醒它,显然这不利于处理机的有效利用。
让权等待方式,即当执行进程必须在某信号量上等待时,就将该进程变为等待状态,并将其插入与此信号量相关的等待队列中,以让出处理机给其他就绪进程。在单机系统中普遍采用让权等待方式。而在多机系统中,为减少进程状态变换而引起的开销,可采取忙等待方式。另外,在具体实现时通常要对Dijkstra的原定义进行改进。

(1)忙等待方式的P、V操作。

vars: integer;
  P(s) :while s≤ 0 do skip;
      s:=s-1V(s) :s:=s+1;

当一进程在值不大于0的信号量s上执行P操作时,将在循环语句while上陷入忙等待,直到其他进程在该信号量s上执行V操作后,解除它的等待。不难看出这种形式的P、V操作完全可用硬件指令来实现。
(2)让权等待方式的P、V操作。
采取这种方式需要对原信号量定义进一步扩充,把信号量由整型量扩充成为记录形式:

    type psem=semaphore
    semaphore=record
    value: integer;
    qucue: pointer to WQ;
    end

即信号量s是二元组s(v,q), v是信号量s的值,它是个整型量,q是指向s等待队列WQ的队首指针。于是P、V操作可分别描述为:

 procedure p (s);
       var s: psem;
       begin
         s.v:=s.v-1;
         if s.v<0 then block(s.q)
       end
procedure V (s);
 var s:psem;
   begin
       s.v:=s.v+1
       if s.v≤0 then wakeup(s.q)
   end

根据上述定义,P、V操作的物理意义可这样来看待。s.v>0表示某类资源的当前可用数。 每执行一次P操作意味着请求分配一个单位的资源,因此描述为s.v:=s.v-1; s.v≤0表示该类资源已不能供分配,因此请求资源的进程将被阻塞在等待队列s.q中,此时s.v的绝对值等于等待队列s.q中的进程数。
执行一次V操作意味着释放一个单位资源,故描述为:s.v:=s.v+1,若s.v≤0,表示在等待队列s.q中有因请求该资源不能满足而被阻塞的进程,因此唤醒等待队列s.q中的第一个或优先数最高的进程,允许其使用该资源。
P操作:意味着请求分配一个单位资源
在这里插入图片描述

V操作:意味着释放一个单位资源
在这里插入图片描述

互斥、同步例子

互斥例子:三个进程共用两个I/O缓冲区
解:设用信号量S表示共享资源,S初始值为2
在这里插入图片描述
同步例子:有A、B两进程,A进程从卡片机读信息入缓冲区,B进程负责加工读进缓冲区的卡片
解:设
信号量S1:缓冲区中有否可供加工的信息,初始值为0;
信号量S2:缓冲区是否为空,初始值为1;
在这里插入图片描述
在这里插入图片描述
在输入进程A中,可以把P(S2)调到V(S1)后面,而把信号量S2的初始值设为0。
用P-V操作描述前趋关系的例子:
信号量还可以描述程序或语句之间的前趋关系。
描述如下:
在这里插入图片描述

var a,b,c,d,e,f,g:=semaphore:=0000000;
 begin
     parbegin
          begin S1;V(a)V(b);end;
          begin P(a);S2;V(c)V(d);end;
          begin P(b);S3;V(e);end; 
          begin P(c);S4;V(f);end;
          begin P(d);S5;V(g);end;
          begin P(e)P(f)P(g);S6;end;
      parend 
end

生产者、消费者问题

生产者-消费者(Producer-Consumer)问题是著名的进程同步问题。它描述一组生产者向 一组消费者提供消息,它们共享一个有界缓冲池,生产者向其中投放消息,消费者从中取得消息。以 下用信号量解决生产者-消费者问题。
问题:
假如缓冲池中有n个缓冲区,每个缓冲区存放一个消息,可利用互斥信号量mutex使诸进程对缓冲池实现互斥访问;利用empty和full计数信号量分别表示空缓冲及满缓冲的数量。又假定这些生产者和消费者互相等效,只要缓冲池未满,生产者可将消息送入缓冲池;只要缓冲池未空,消费者可从缓冲池取走一个消息。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
其中,mutex,empty,full的初始值分别为1,n,0; 读者可以自行分析这两个进程如何实现同步。
欢迎大家加我微信交流讨论
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程子的小段

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值