版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Hanani_Jia/article/details/83152421
我们上次通过代码实现了进程间的互斥操作,解决了wps和word同时都去操作我们的队列的话怎么解决这个问题,但是打印机这边又出现了问题,因为我们的进程队列是有限制的,正常来说打印机就在我们的槽里获取数据打印就可以了,但是如果说我们槽满了,这时候应该怎么办?Wps和word是不是都要等着队列空了再往里边放,再或者如果说队列全部空了,打印机也要等着其他进程往里边放东西,所以wps、word和打印机之间也是要保持同步的。这就是所谓的生产者消费者模型。
当有多个消费者和多个生产者的时候,情况就变的复杂了起来,你要保证消费者和消费者之间的互斥,也要保证生产者和生产者之间的互斥问题,还要保证生产者和消费者之间的同步和互斥的问题。
在上边说的例子这种,wps和word就是我们的生产者,而我们的打印机就是消费者。我们之前介绍的锁能够解决互斥,但是不能够解决多个进程之间的同步问题。
当我们只有一个生产者和只有一个消费者的时候问题相对简单一些,问题的核心是要保证不能说临界区满了,生产者还在往里边写入数据,不能让临界区空了,消费者仍然从里边获取数据。生产者和消费者之间对临界区的访问是一个互斥问题,但是两者有是一个相互协作的问题,只有在生产者生产了之后,消费者才能去读取数据,所以他们也是同步问题。这时候信号量就上场了。
所谓的信号量说白了就是一个整数,基于这个整数有两个操作一个是wait一个是signal
这里的++,--的和我们的互斥锁那里很像,他是怎么来解决这个问题的呢?
上边说到的wps和word都是生产者,当他们想执行操作的时候,先看一下队列是不是有空的位置,如果有空的位置,那就进行加锁,加锁的过程就看谁快了,谁先抢到这个锁,谁就可以去执行操作,执行完自己的操作之后要去释放锁,因为另一个word可能在等着去操作这个队列,释放锁之后还有修改full的值来告诉可能正在等待的打印机,有文件可以操作了。
我们上边写到的程序是while循环来等待进程,但是这样的话我们的CPU就会被一直占用,我们就需要对其进行一定的改进,让等待的进行进入休眠。
这里我们通过一个实际的例子来了解一下实现多线程间的同步与互斥,当有多个生产者多个消费者的时候怎么去操作。
/*桌子上有一只盘子,每次只能向其中放入一个水果。爸爸专向盘子中放苹果,妈妈专向盘子中放橘子,
儿子专等吃盘子中的橘子,女儿专等吃盘子中的苹果。
只有盘子为空时,爸爸或妈妈就可向盘子中放一个水果;
仅当盘子中有自己需要的水果时,儿子或女儿可以从盘子中取出。*/
semaphore plate = 1, apple = 0, orang = 0;
Dad()//父亲进程
{
while (1)
{
P(plate);//只能有一个人操作(放置、获取)盘子
put a apple;
V(apple);//让apple的量+1,通知等待苹果的进程可以来获取苹果了
}
}
Mom()//母亲进程
{
while (1)
{
P(plate);
put a orang;
V(orang);
}
}
Son()//儿子进程
{
while (1)
{
P(orang);//这里要注意,不用P(plate)因为盘子容量只有1,当儿子拿橘子的时候说明盘中有橘子没苹果,女儿并不会操作盘子
catch a orang;
V(plate);//通知等待的生产者,盘子可以放东西了
}
}
Daugther()//女儿进程
{
while (1)
{
P(apple);
catch a apple;
V(apple);//通知等待的进程,可以放东西了
}
}