5.P、V操作和消费者问题 原

时间:2022-06-19
本文章向大家介绍5.P、V操作和消费者问题 原,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

用信号量实现互斥

Var mutex:semaphoer:=1;
	Begin
		Parbegin
		Process1:begin		//第一个进程
				repeat
					wait(mutex);
					critical section
					signal(mutex);
					remainder section
				until false;
					end;
		Process2:begin		//第二个进程
			repeat
				wait(mutex);		//申请资源
				critical section	//使用临界区
				singal(mutex);	//释放资源
				remainder section	//剩余区代码
			until false;
			end
	Parend

注意

  • 在实现互斥时,wait(mutex)和singal(mutex)必须成对地出现
  • 缺wait(mutex)将会引起系统混乱,不能保证对临界资源的互斥访问
  • 缺singal(mutex)将会使该临界资源永久不会被释放

经典的同步问题

  • 生产者——消费者问题
  • 读者——写者问题
  • 哲学家进餐问题

生产者——消费者问题

一组生产者进程生产产品给一组消费者进程消费。为使他们并发执行,设一个有n个缓冲区的缓冲池,生产者一次向一个缓冲区中投入消息,消费者从一个缓冲区中取得消息。生产者——消费者问题实际上是相互合作进程关系的一种抽象。

例子

  • 在输入时,输入进程是生产者,计算进程是消费者
  • 在输出时,计算进程是生产者,打印进程是消费者

制约关系

  • 不允许消费者进程到一个空缓冲区中取产品
  • 不允许生产者进程到一个已满且还没被取走的缓冲区中投放产品

用记录型信号量解决生产者——消费者问题

  • 设有n个缓冲区,每个缓冲区存放一个消息,用互斥信号量mutex对缓冲池实现互斥访问
  • 利用资源信号量empty和full分别表示缓冲池中空缓冲区及满缓冲区的数量,又假定这些生产者和消费者相互等效,只要缓冲池未满,生产者便可将消息送入缓冲池;只要缓冲池未空,消费者便可从缓冲池取走一个消息。
var mutex:semaphore:=1;
	empty:semaphore:=n;
	full:semaphore:=0;
	
buffer:array[0,1,……,n-1] of item;	//生产者生产出来的一个数据就是item
	in,out:integer:=0,0;	//in记录放入数据的地址,out记录取出数据的地址,其实就是buffer下标

生产者进程:

Procedure:begin
	repeat
		……
	procedure an item nextp;  //生产一个数据(下一个)
		……
		wait(empty);	//申请一个空缓冲区,申请成功,empty信号量减1
		wait(mutex);
		Buffer(in):=nextp;	  //将nextp放入下标是in的缓冲区中
		in:=(in+1) mod n;
		singal(mutex);			//释放缓冲区
		singal(full);			//将full信号量加1
		until false;
		end;

消费者进程

consumer:begin
		repeat
			wait(full);		//申请一个缓冲区
			wait(mutex);	//含义是判断当前有没有生产者在使用申请的缓冲区
			nextc:=Buffer(out);
			out:=(out+1) mod n;
			singal(mutex);
			singal(empty);		//释放一个空缓冲区,empty加1
		Consumer the item in nextc;
		until false;
		end;

注意

  • 每个程序中互斥的wait(mutex)和singal(mutex)必须成对出现。
  • 对资源信号量empty和full的P、V操作成对出现,但它们分别处于不同的程序中。例如P在计算进程中,而V在打印进程中,计算进程若因执行P而阻塞,则以后将由打印进程将它唤醒。
  • 每个程序中的P操作顺序不能颠倒。应先执行对资源信号量的P操作,然后再执行对互斥信号量的P操作,否则可能引起进程死锁。
  • V操作的顺序无所谓,都可以。

(adsbygoogle = window.adsbygoogle || []).push({});