C++ 如果我评论“为什么程序会陷入僵局?”;而";块“怎么说?”;“收益率”;它的效果如何?
我正在学习条件变量并运行一些示例。我很好奇,如果我对块进行注释,为什么下面的代码会死锁。这是一个使用condition_变量的简单消费者和生产者示例。我认为这是一个僵局问题,不是吗C++ 如果我评论“为什么程序会陷入僵局?”;而";块“怎么说?”;“收益率”;它的效果如何?,c++,deadlock,condition-variable,C++,Deadlock,Condition Variable,我正在学习条件变量并运行一些示例。我很好奇,如果我对块进行注释,为什么下面的代码会死锁。这是一个使用condition_变量的简单消费者和生产者示例。我认为这是一个僵局问题,不是吗 #include <iostream> #include <thread> #include <mutex> #include <condition_variable> using namespace std; mutex mtx; condition_variab
#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("%d\n", 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();
}
#包括
#包括
#包括
#包括
使用名称空间std;
互斥mtx;
条件变量cv;
国际货运=0;
bool装运可用()
{
退货!=0;
}
无效消耗(int cnt)
{
对于(int i=0;i
如果我取消对该块的注释,它运行得很好。因此,请仔细查看以下极有可能出现的情况:
main()
启动使用者线程main()
将其锁定,增加cargo
,并触发通知,然后通过作用域旋转十次释放互斥锁main()
现在运行到join
consumer线程cargo
确实为零,所以它等待条件变量(在过程中释放互斥锁),等待永远不会出现的信号。唯一发送该信号的是main()
,它只是在等待消费者线程加入,而这现在永远不会发生shipping\u可用
函数检查谓词数据(即必须由隐藏在其中的互斥锁保护的数据,不仅用于修改,也用于检查)。检查未锁定互斥锁的main
是否会导致竞争条件
我的建议是把货物减少一件,而不是把它归零。或者,您可以在归零之前将
i
增加cargo
的值,从而加速i
上升到cnt
限制,但您似乎使用了上升的货量,因此,您必须做出相应的其他调整。在确认有什么需要等待之前,您不能调用等待。这就是互斥的目的。@DavidSchwartz我不确定我是否理解你的评论,David。上述潜在工作流程中是否有遗漏的内容?如果是这样的话,一定要找出答案并把它加进去。我正试图把你想要表达的概念具体化。@DavidSchwartz啊。。。好啊谢谢,非常感谢。我认为这正是原因,因为程序最终只输出“10”,然后陷入困境。这只是一些社论中的示例代码。再次感谢!