操作系统-------用P,V操作解决生产者和消费者问题(详解!!!)

问题:

        系统中有一组生产者进程和一组消费者进程,生产者每次生产一个产品放入缓冲区,消费者每次从缓冲区取出一个产品并使用(注:这里的产品可以理解成某种数据)。

条件:生产者、消费者共享一个初始化为空的、大小为n的缓冲区。

提示:

        做这一题之前一定要熟练的掌握进程的互斥和进程的同步,一定要会!!一定要会!!一定要会!

        不会的话可以   点击这里!!!

题目分析:

        1.首先读题之后就容易知道,咱们现在有一个缓冲区,生产者负责生产产品,然后把产品放到缓冲区里面,生产产品的前提条件是缓冲区未满,缓冲区的大小为n。消费者负责使用产品,但是使用产品的前提条件缓冲区里面有产品。

        2.下面分析一下互斥和同步的问题,因为只有一个缓冲区(生产者放产品,消费者取产品),所以这里可以把缓冲区看成临界资源(类似多个打印机进程打印那样),而且多个生产者之间不能同时往缓冲区中放产品(可能会造成覆盖),多个消费者也不可以同时在缓冲区中取产品,也不可以生产者放产品的同时,消费者取产品。

          经过上面的分析,可以得出进程的互斥和进程同步的结论

 结论:

        互斥------------因为缓冲区是临界资源,各种进程必须互斥的访问(即不能同时访问)。

        同步1-----------只有缓冲区不空时,消费者才可以从缓冲区中取产品,即  “ 先生产后消费 ”。

        同步2-----------只有缓冲区不满时,生产者才可以往缓冲区中放产品,即  “ 先消费后生产”。

具体解法:

semaphore mutex=1;//互斥信号量 ,实现对缓冲区的互斥访问 
semaphore full =0;//同步1信号量,表示产品的数量 
semaphore empty=n;//同步2信号量,表示空闲区的数量 

producer()
{
	while(1)
	{
		生产一个产品;
		P(empty); 
		P(mutex);
		将产品放入缓冲区;
		V(mutex);
		V(full); 
	}
} 

consumer()
{
	while(1)
	{
		P(full); 
		P(mutex);
		从缓冲区取出一个产品;
		V(mutex);
		V(empty); 
		使用一个产品;
	}
} 

讨论:

      1.生产者和消费者进程都有两个P操作在一块,可以把生产者的两个P操作或者消费者的两个P操作调换顺序吗?

     答案:无论是生产的的两个P操作,还是消费者的两个P操作都不可以调换顺序。假如生产的的两个P操作调换了顺序(包含了消费者换或者不换两种情况),现在有一种情况是empy=0,full=n,在这种情况下,假设消费者进程先执行,

生产一个产品------>P(mutex)占用缓冲区,这时候除非等消费者释放缓冲区,不然谁也无法使用缓冲区了

-------->P(empty)因为empty=0,所以执行block原语,将生产的进程从运行态转到阻塞态,经过这一步之后消费者进程阻塞,只能等切换进程,假如切换到消费者进程,无论P(mutex)在P(full)前还是在P(full)后,总归要执行P(mutex),但是生产者正在占用缓冲区,因此就产生了死锁。

       调换消费的的两个P操作顺序也是类似,在empty=n,full=0的情况下也不满足,如果不懂得话,自己可以按照上面的进行推导。 

      2.生产者和消费者进程都有两个V操作在一块,可以把生产者的两个V操作或者消费者的两个V操作调换顺序吗?

      答案:可以

注意:如果看完分析还是不懂,再去把进程的互斥和进程的同步看一遍,一点要把这两个弄清楚。

猜你喜欢

转载自blog.csdn.net/weixin_44820625/article/details/106083352