algorithm - 生产者-消费者,为什么不用一个信号量来实现呢?

标签 algorithm operating-system

使用我的想法,只需要一个信号量(互斥体除外)

    n = 10
    mutex = 1

 producer:   //This is producer
    P(mutex)
    V(n)
    V(mutex)   

 cosumer:    //This is consumer
    P(mutex)
    P(n)
    V(mutex)

下面使用传统的两个信号量来实现。

    n = 10
    empty = 0
    mutex = 1

 producer:   //This is producer
    P(empty)
    P(mutex)
    produce();
    V(mutex)
    V(n)

 consumer:    //This is consumer
    P(n)
    p(mutex)
    consume()
    V(mutex)
    V(empty)

最佳答案

在环形缓冲区生产者-消费者模式中,生产者将项目放入有限大小的缓冲区中,而消费者从该缓冲区中删除项目。

理解该模式的关键是理解生产者也是消费者——它消耗空的缓冲区槽。

信号量的目的是控制对计数资源的关键访问。由于缓冲区中的项目是计数资源,空缓冲区槽也是计数资源,因此需要两个信号量。

出现冗余,因为两个信号量计数不独立。它们的总和保持不变,并且等于缓冲区大小。而且,两个线程队列不是独立的。在任何时刻,只有一个信号量会持有任何挂起的线程,因为永远不会有生产者和消费者同时等待。然而,冗余还不够完整,无法消除其中一个信号量。

如果我理解的话,您建议的构造将会失败,因为当缓冲区已满时,生产者不会停止。此外,如果消费者等待空缓冲区,它会阻止生产者到达其“V(n)”操作。

冗余确实表明生产者-消费者对可能可以实现更有效的同步,而且实际上已经提出了许多其他同步。特别参见'monitor'技术。

关于algorithm - 生产者-消费者,为什么不用一个信号量来实现呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19341465/

相关文章:

c - 硬件进程是 "sandboxed"吗?

Ruby gem rmagick 无法安装在 Mac OS X 上

c - C库如何调用内核系统调用

windows - UDP 数据包,被 Wireshark 看到,被(甚至没有到达)WSARecvFrom 丢弃

sql - 计算同一组成员的有效方法

algorithm - 直观理解 Adam 优化器

c++ - 当有多个查询时,检查某些子数组是否已排序的有效方法是什么?

javascript - 如何优化搜索

c++ - 使用 glFrustum 改变坐标

linux - 如何使用 X 窗口为 Linux 操作系统界面创建 GUI?