我对加涅(Gagne)在“操作系统概念”一书中显示的有界缓冲区问题中的信号量(muxtex,空)的排序有疑问。
以下是我所引用的代码的两个图像。
首先)绑定缓冲区。
第二)插入方法。
我的问题是:在insert方法中的mutex.acquire()之前具有empty.acquire()的原因是什么?
还不是更清楚的是,mutex.acquire()是否在empty.acquire之前?
我知道就功能而言,顺序并不重要。但是作者为什么在mutex.acquire之前调用empty.acquire是有原因的?
最佳答案
该顺序对于缓冲区已满的情况很重要。 empty.acquire()
具有阻塞线程的作用,直到尝试在缓冲区中添加一项之前缓冲区中至少有一个空闲插槽。
如果反转,该函数将如下所示:
public void insert(Object item) {
mutex.acquire();
empty.acquire();
...
如果在缓冲区已满时调用此方法,则在
mutex
上线程被阻塞时将获取empty.acquire()
。然后,如果另一个线程调用remove()
释放缓冲区插槽,它将在mutex.acquire()
上阻塞。现在,不能添加任何新元素,因为缓冲区已满,并且所有删除对象的尝试都将阻止。