为什么在生产者使用者问题中需要2个变量来表示信号量?

时间:2018-11-11 02:05:45

标签: operating-system synchronization mutex semaphore producer-consumer

生产者消费者的标准实现方式如下:

  • useQueue互斥锁
  • 大小为emptyCount
  • N信号量
  • 大小为fullCount
  • N信号量

生产:

down(emptyCount)
down(useQueue)
putItemIntoQueue(item)
up(useQueue)
up(fullCount)

消费:

down(fullCount)
down(useQueue)
item ← getItemFromQueue()
up(useQueue)
up(emptyCount)

如果down具有非正值,则线程等待。 up推高计数

摘自this维基百科文章

为什么我们不能有这样的东西?

class NewSemaphore {
    int capacity, permits;

    /**
     * Initialize the semaphore with a max capacity
     * @param n the max capacity
     */
    NewSemaphore(int n) {
        capacity = n;
        permits = 0;
    }

    /**
     * We usually never check this. Check if it's within limits.
     * If not, wait
     */
    synchronized void up() {
        if (permits >= capacity) {
            wait();
        } else {
            permits++;
            notify();
        }
    }

    /**
     * Standard down/acquire function
     */
    synchronized void down() {
        if (permits <= 0) {
            wait();
        } else {
            permits--;
            notify();
        }
    }
}

这将被称为:

生产:

up(mySemaphore)
down(useQueue)
putItemIntoQueue(item)
up(useQueue)

消费:

down(mySemaphore)
down(useQueue)
item ← getItemFromQueue()
up(useQueue)

为什么我们需要两个不同的变量emptyCountfullCount

2 个答案:

答案 0 :(得分:1)

不,两个信号灯不是必须的,这是一个用C编写的信号灯解决方案,请在此处查看: https://github.com/heguihua/unisem

答案 1 :(得分:0)

有两个信号量,因为我们需要检查两件事。首先是消费者在没有什么可消费的情况下等待,其次是生产者在队列已满的情况下等待。

您的想法将使生产者继续生产,直到耗尽内存或其他资源为止。