我正在研究操作系统中的同步,我对解决(多个)生产者 - 消费者问题(使用有界缓冲区)的典型方法(从我所见)感到有点困惑。我见过的唯一解决方案(据我记得)是以下(伪代码),其中N
是缓冲区的容量:
Semaphore<Integer> emptyCount = N, fullCount = 0;
Lock bufLock; // Starts unlocked
produce:
emptyCount.down(); // If possible, decrement `emptyCount`; otherwise, block until possible
bufLock.lock(); // Lock buffer before writing
// *CRITICAL SECTION: write something to buffer*
bufLock.unlock(); // Unlock buffer after writing
fullCount.up(); // If possible, increment `fullCount`; otherwise, block until possible
consume:
fullCount.down(); // If possible, decrement `fullCount`; otherwise, block until possible
bufLock.lock(); // Lock buffer before reading
// *CRITICAL SECTION: read something from buffer*
bufLock.unlock(); // Unlock buffer after reading
emptyCount.up(); // If possible, increment `emptyCount`; otherwise, block until possible
但是,不应该像以下那样只使用一个锁(二进制信号量)的解决方案?:
Lock bufLock; // Starts unlocked
Integer bufCrtSize = 0;
produce:
bufLock.lock(); // Lock buffer before attempting to write
// If buffer is full, unlock buffer and try again with next `produce` call
if (bufCrtSize == N):
bufLock.unlock();
// *Yield current thread to scheduler*
return;
// *CRITICAL SECTION: write something to buffer*
++bufCrtSize;
bufLock.unlock(); // Unlock buffer after writing
consume:
bufLock.lock(); // Lock buffer before attempting to read
// If buffer is empty, unlock buffer and try again with next `consume` call
if (bufCrtSize == 0):
bufLock.unlock();
// *Yield current thread to scheduler*
return;
// *CRITICAL SECTION: read something from buffer*
--bufCrtSize;
bufLock.unlock(); // Unlock buffer after reading
如果后一种解决方案有效,那么它是不是被使用的原因(就我所见),因为它更慢?它不应该导致任何死锁,因为如果CS无法执行,锁解锁,并且它不应该导致活锁,因为只有一个'资源'。
这里可能有一个类似的问题,但我找不到;如果存在,请随意在评论中链接它。
谢谢你的时间!