gpt4 book ai didi

multithreading - 多线程编程-生产者消费者

转载 作者:行者123 更新时间:2023-12-03 13:05:00 24 4
gpt4 key购买 nike

wikipedia中提到的生产者消费者问题的“实现不充分”的伪代码如下。据说此解决方案具有可能导致死锁的竞争状况。

我的问题是:不会像下面那样修改唤醒另一个线程的条件,可以解决可能的死锁问题。这样,不仅不会丢失一个唤醒,而且还会丢失多个唤醒,或者我丢失了某些东西。试图在这里理解。

int itemCount = 0;

procedure producer() {
while (true) {
item = produceItem();

if (itemCount == BUFFER_SIZE) {
sleep();
}

putItemIntoBuffer(item);
itemCount = itemCount + 1;

//if (itemCount == 1) <<<<<<<< change this to below condition
if(itemCount > 0)
{
wakeup(consumer);
}
}
}

procedure consumer() {
while (true) {

if (itemCount == 0) {
sleep();
}

item = removeItemFromBuffer();
itemCount = itemCount - 1;

//if (itemCount == BUFFER_SIZE - 1) <<<<<<< Change this to below
if(itermCount < BUFFER_SIZE)
{
wakeup(producer);
}

consumeItem(item);
}
}

最佳答案

Wouldn't just modifying the conditions of wakeing up the other thread as below solve the possible deadlock issue.



不,比赛条件仍然存在。问题是有多个线程在进行消耗和/或生产。当某个消费者(例如)被唤醒并被告知有待处理的物品时,它可能会去掉该物品,但是其他一些线程(或多个线程)已经到达那里。

解决方案是执行以下操作:
lock() {
while (itemCount == 0) {
sleep();
}

item = removeItemFromBuffer();
itemCount = itemCount - 1;
}

因此,即使使用者被唤醒,它也会立即通过 itemCount循环再次检查 while是否不为0。即使 itemCount增加了,另一个线程也可能在得到信号的线程有机会采取行动之前删除了该元素并减小了 itemCount。那是种族。

对于生产者而言,这是相同的,尽管竞争是为了阻止生产者过度填充缓冲区。生产者可能会因为存在可用空间而被唤醒,但是到将项目放入缓冲区时,其他线程已经击败它并重新填充了缓冲区。它必须再次测试以确保在唤醒后还有空间。

我从我的网站 Producer Consumer Thread Race Conditions上逐行详细介绍了这场比赛。那里也有一个小的测试程序来演示这个问题。

要意识到的重要一点是,在大多数锁定实现中,都有线程队列等待获取对锁的访问权。当信号发送到线程时,它首先必须重新获取该锁,然后才能继续。发出线程信号后,它将转到BLOCK队列的末尾。如果还有其他线程正在等待锁但没有等待,则它们将在唤醒线程之前运行并窃取项目。

这与关于类似代码中的 while循环的问题非常相似。不幸的是,被接受的答案不能解决这种竞争状况。请考虑升级 my answer to a similar question here。虚假唤醒是一个问题,但真正的问题是维基百科在谈论种族条件。

关于multithreading - 多线程编程-生产者消费者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19282999/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com