如果我对"while"块发表评论,为什么程序会死机?其中的"yield"线有何影响?
Why the program get deadlocked if I comment the "while" block? How does the "yield" line in it effect?
我正在学习condition_variable并运行一些示例。我很好奇,如果我对块进行注释,为什么以下代码会死锁。这是一个使用 condition_variable 的简单使用者和生产者示例。我认为这是一个僵局问题,不是吗?
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
mutex mtx;
condition_variable cv;
int cargo = 0;
bool shipment_available()
{
return cargo != 0;
}
void consume(int cnt)
{
for (int i = 0; i < cnt; i++)
{
unique_lock<mutex> lck(mtx);
cv.wait(lck, shipment_available);
printf("%dn", cargo);
cargo = 0;
}
}
int main()
{
thread consumer_thread(consume, 10);
for (int i = 0; i < 10; i++)
{
//while (shipment_available()) // Dead lock without this block
//{
// std::this_thread::yield();
//}
unique_lock<mutex> lck(mtx);
cargo = i + 1;
cv.notify_one();
}
consumer_thread.join();
}
如果我取消注释该块,它运行良好。
因此,请了解这种极有可能的可能性:
main()
启动使用者线程。- 在线程获取互斥锁之前,
main()
锁定它,递增cargo
,并触发通知,然后通过作用域轮换十次释放互斥锁。 main()
现在向下运行以join
使用者线程。- 消费者最终获得互斥锁,并准备等待给定谓词的条件变量(非零货物(。
- 谓词已为 true,因此不执行等待。
- 消费者将货物归零,然后通过范围旋转释放互斥锁。
- 消费者第二次循环,锁定互斥锁,然后检查谓词,只是现在谓词是假的,因为
cargo
确实为零,所以它等待条件变量(释放过程中的互斥锁(一个永远不会出现的信号。唯一发送过该信号的是main()
,它只是在等待消费者线程加入,现在这种情况永远不会发生。
简而言之,您似乎相信条件变量信号会叠加。事实并非如此。如果在发布通知时没有人主动等待通知,它就会丢失到以太币中。
最后,这很重要,您的"修复"本身是完全错误的。shipment_available
函数检查谓词数据(即必须由覆盖它的互斥锁保护的数据,不仅用于修改,而且用于检查(。检查互斥锁是否未锁定main
是争用条件的秘诀。
我的建议是将货物减少一个,而不是将其归零。或者,您可以在将i
值归零之前将cargo
的值递增,从而加速i
的上升到cnt
限制,但您似乎使用的是递增的货物量,因此您必须相应地进行其他调整。
相关文章:
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 函数何时会在c++中包含stack_Unwind_Resume调用
- Python中的for循环与C++有何不同
- 为什么擦除方法会影响结束方法
- 内联如何影响模块接口中的成员函数
- 为什么返回类型的'const'限定符对标有 __forceinline/内联的函数没有影响?
- 在容量内调整矢量大小时的性能影响
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 在C++中释放内存期间,迭代器与指针有何不同
- 未达到的情况会影响开关外壳性能
- 循环仅对第一行正常工作.其他行不受 for 的影响
- 处理影响跨不同线程共享对象的定时回调的最佳方法是什么?
- 模板如何影响C++中隐式声明的规则?
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- 如果我们使用 notify_one() 来唤醒线程,我们还需要 yield() - C++?
- 命名空间信息会影响C++的可读性
- "virtual"对C++析构函数有何影响?
- 如果我对"while"块发表评论,为什么程序会死机?其中的"yield"线有何影响?
- Qt也不例外.这对C++代码有何影响
- 基例如何影响使用递归函数的哪些行