美文网首页
生产者消费者问题

生产者消费者问题

作者: NiNko | 来源:发表于2020-03-13 21:30 被阅读0次

    生产者消费者问题是一个经典的同步问题,问题的描述如下:

    一组生产者进程和一组消费者进程共享一个初始为空,大小为n的缓冲区,只有缓冲区没满时,生产者才能把消息放入缓冲区,否则必须等待,只有缓冲区不空时,消费者才能从中取出消息,否则只能等待。由于缓冲区时临界资源,只允许一个生产者放入消息,或者一个消费者取出消息。


    问题分析:

    • 生产者与消费者对缓冲区的访问是互斥关系,同时又是一个相互协作关系,即只有生产者产生消息,消费者才能取出消息,因此又是一个同步问题。
    • 信号量设置,设置一个信号量mutex为互斥信号量,初始值为1,信号量full记录缓冲池中已满的缓冲区数目,初始为0,信号量empty记录缓冲池中空的缓冲区数目,初始为n。

    实现如下

    semaphore mutex=1;
    semaphore empty=n;
    semaphore full=0;
    
    producer(){
        while(1){
            //生产一个消息
            P(empty);//获取空缓冲区单元
            P(mutex);//进入临界区
            //将消息添加到缓冲区
            V(mutex);
            V(full);
        }
    }
    
    consumer(){
        while(1){
            P(full);
            P(mutex);
            //取出一个消息
            V(mutex);
            V(empty)
        }
    }
    

    分析:

    首先对于互斥问题,需要设置一个互斥信号量,同时为保证只有一个进程能够进入临界区,信号量需设置为1。对于同步问题,因为缓冲池大小为n,缓冲区空时生产者可以放入消息,缓冲区满时,消费者可以取出消息,因此设置两个信号量,分别对应满的缓冲区和空缓冲区数目,两个信号量相加应为n。

    同时,对empty和full的P操作,需放在mutex之前。这是因为生产者线程只对empty有需求,当生产者线程对empty执行P操作后,empty为0,对消费者线程并没有影响。而若是对mutex的P操作放在前,假设生产者已经将缓冲区放满,此时empty为0,消费者也没有取出消息。而此时又运行生产者线程时,生产者先封锁mutex信号量,然后执行P(empty)操作,阻塞后,其等待消费者线程取出消息并唤醒自身。此时执行消费者线程时,由于mutex已经被生产者锁定,消费者也会阻塞,希望生产者唤醒自己。那么双方都会阻塞。

    相关文章

      网友评论

          本文标题:生产者消费者问题

          本文链接:https://www.haomeiwen.com/subject/itmyshtx.html