创建死锁的整数缓冲区的实现
An implementation of integer buffer that creates deadlock
让我们考虑以下伪代码:
class OneBuf{
Mutex m;
CondVar cv;
int buffer;
bool full;
void put(int data){
m.lock();
while(full){
cv.wait(m);
}
buffer = data;
full = true;
cv.signal();
m.unlock();
}
int get(){
int data;
m.lock();
while(!full){
cv.wait(m);
}
full = false;
data = buffer;
cv.signal();
m.unlock();
return data;
}
}
有人告诉我上面的代码是容量为一个整数的缓冲区的错误实现,第 14 行和第 26 行应该执行 cv.broadcast()而不是 cv.signal()。你能帮我证明这个更正是必要的吗?通过显示初始代码的执行 3 threads(例如 1 个生产者和 2 个消费者)造成死锁(即所有 3 个线程结束起来睡觉)?
我不知道是否需要图论来证明这一点。
如果应用程序处于一个消费者处于监视器中而其他两个线程正在等待它的状态,则仅向一个线程发出信号可能会唤醒另一个消费者,后者将因缓冲区现在为空而被阻塞。
并且由于那个被阻塞的消费者没有发出信号,生产者将不会醒来。随着缓冲区为空,第一个消费者最终将被阻塞。
那里的一条路径从一个空缓冲区开始(两个消费者都在等待),生产者有两个项目要放入缓冲区。然后,在第二次放置时,它将被阻止,其中一位消费者将进入。
让我们考虑以下伪代码:
class OneBuf{
Mutex m;
CondVar cv;
int buffer;
bool full;
void put(int data){
m.lock();
while(full){
cv.wait(m);
}
buffer = data;
full = true;
cv.signal();
m.unlock();
}
int get(){
int data;
m.lock();
while(!full){
cv.wait(m);
}
full = false;
data = buffer;
cv.signal();
m.unlock();
return data;
}
}
有人告诉我上面的代码是容量为一个整数的缓冲区的错误实现,第 14 行和第 26 行应该执行 cv.broadcast()而不是 cv.signal()。你能帮我证明这个更正是必要的吗?通过显示初始代码的执行 3 threads(例如 1 个生产者和 2 个消费者)造成死锁(即所有 3 个线程结束起来睡觉)?
我不知道是否需要图论来证明这一点。
如果应用程序处于一个消费者处于监视器中而其他两个线程正在等待它的状态,则仅向一个线程发出信号可能会唤醒另一个消费者,后者将因缓冲区现在为空而被阻塞。
并且由于那个被阻塞的消费者没有发出信号,生产者将不会醒来。随着缓冲区为空,第一个消费者最终将被阻塞。
那里的一条路径从一个空缓冲区开始(两个消费者都在等待),生产者有两个项目要放入缓冲区。然后,在第二次放置时,它将被阻止,其中一位消费者将进入。