为什么在生产者消费者问题中需要两个变量来实现信号量?

3

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

  • 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则会增加计数。

引用自维基百科文章。

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

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();
        }
    }
}

这段代码将会被这样调用: produce:
up(mySemaphore)
down(useQueue)
putItemIntoQueue(item)
up(useQueue)

消费:

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

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

"synchronized" 是什么意思,因为你似乎在其中等待? - Martin James
这是Java提供的监视器。它用于在信号量对象上进行原子语句。 - aneesh joshi
2个回答

1

0

有两个信号量是因为我们要同时检查两件事情。第一,如果没有要消费的东西,消费者需要等待;第二,如果队列已满,生产者需要等待。

你的想法会让生产者继续生产直到他们耗尽内存或其他资源。


信号量有一个上限,它不会一直生产。 - aneesh joshi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接