Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么重复使用条件变量的互斥将导致死锁? 当我在C++ 11中寻求实现 STD::条件变量变量< /> >时,我遇到了一个代码。在上面的问题中,这样的代码可以正确执行,而在函数void g()中添加注释行偶尔会导致死锁。我想知道为什么以及std::condition\u variable::wait()(这让我很困惑)的确切内部机制。提前谢谢 #include <thread> #include <mutex> #include <condition_variable> #include <iostream> std::mutex mtx; std::condition_variable cv; void f() { { std::unique_lock<std::mutex> lock( mtx ); cv.wait( lock ); } std::cout << "f()\n"; } void g() { // std::unique_lock<std::mutex> lock( mtx ); adding this line will result in // deadlock. std::this_thread::sleep_for( std::chrono::seconds(1) ); cv.notify_one(); } int main() { for (int i = 1; i <= 100; i++) { std::cout << i << std::endl; std::thread t1{ f }; std::thread t2{ g }; t2.join(); t1.join(); } } #包括 #包括 #包括 #包括 std::互斥mtx; std::条件变量cv; void f(){ { std::唯一锁(mtx); cv.等待(锁定); } std::cout_C++_Multithreading_C++11 - Fatal编程技术网

为什么重复使用条件变量的互斥将导致死锁? 当我在C++ 11中寻求实现 STD::条件变量变量< /> >时,我遇到了一个代码。在上面的问题中,这样的代码可以正确执行,而在函数void g()中添加注释行偶尔会导致死锁。我想知道为什么以及std::condition\u variable::wait()(这让我很困惑)的确切内部机制。提前谢谢 #include <thread> #include <mutex> #include <condition_variable> #include <iostream> std::mutex mtx; std::condition_variable cv; void f() { { std::unique_lock<std::mutex> lock( mtx ); cv.wait( lock ); } std::cout << "f()\n"; } void g() { // std::unique_lock<std::mutex> lock( mtx ); adding this line will result in // deadlock. std::this_thread::sleep_for( std::chrono::seconds(1) ); cv.notify_one(); } int main() { for (int i = 1; i <= 100; i++) { std::cout << i << std::endl; std::thread t1{ f }; std::thread t2{ g }; t2.join(); t1.join(); } } #包括 #包括 #包括 #包括 std::互斥mtx; std::条件变量cv; void f(){ { std::唯一锁(mtx); cv.等待(锁定); } std::cout

为什么重复使用条件变量的互斥将导致死锁? 当我在C++ 11中寻求实现 STD::条件变量变量< /> >时,我遇到了一个代码。在上面的问题中,这样的代码可以正确执行,而在函数void g()中添加注释行偶尔会导致死锁。我想知道为什么以及std::condition\u variable::wait()(这让我很困惑)的确切内部机制。提前谢谢 #include <thread> #include <mutex> #include <condition_variable> #include <iostream> std::mutex mtx; std::condition_variable cv; void f() { { std::unique_lock<std::mutex> lock( mtx ); cv.wait( lock ); } std::cout << "f()\n"; } void g() { // std::unique_lock<std::mutex> lock( mtx ); adding this line will result in // deadlock. std::this_thread::sleep_for( std::chrono::seconds(1) ); cv.notify_one(); } int main() { for (int i = 1; i <= 100; i++) { std::cout << i << std::endl; std::thread t1{ f }; std::thread t2{ g }; t2.join(); t1.join(); } } #包括 #包括 #包括 #包括 std::互斥mtx; std::条件变量cv; void f(){ { std::唯一锁(mtx); cv.等待(锁定); } std::cout,c++,multithreading,c++11,C++,Multithreading,C++11,您应该将条件变量与实际条件相关联,并考虑虚假唤醒。在您的示例中,如果您先向条件变量发送信号,然后通过wait()继续在条件变量上休眠,则代码可能会死锁 因此,理想情况下,您的代码应该如下所示(如果您在睡眠前发出信号,则更改后的条件将检测到您不应该睡眠) void f(){ { std::唯一锁(mtx); while(一些布尔值){ cv.等待(锁定); } } std::cout答案在您提供的链接的示例中: 但是,您的示例在使用notify_one()局部变量之前不会解锁它。您的g()函数应该

您应该将条件变量与实际条件相关联,并考虑虚假唤醒。在您的示例中,如果您先向条件变量发送信号,然后通过
wait()
继续在条件变量上休眠,则代码可能会死锁

因此,理想情况下,您的代码应该如下所示(如果您在睡眠前发出信号,则更改后的条件将检测到您不应该睡眠)

void f(){
{
std::唯一锁(mtx);
while(一些布尔值){
cv.等待(锁定);
}
}

std::cout答案在您提供的链接的示例中:

但是,您的示例在使用
notify_one()
局部变量之前不会解锁它。您的
g()
函数应该如下所示:

void g() {
    std::unique_lock<std::mutex>  lock( mtx );
    std::this_thread::sleep_for( std::chrono::seconds(1) );
    lock.unlock();
    cv.notify_one();
}
void g(){
std::唯一锁(mtx);
std::this_thread::sleep_for(std::chrono::seconds(1));
lock.unlock();
cv.通知_one();
}

在创建运行
g()
的线程之前创建运行
f()
的线程并不保证
f()
将在
g()
之前开始运行。当
g()时
首先启动,它抓住锁,休眠一秒钟,然后notify的条件变量。因为没有人在等待条件,所以notify无效。当
g()
返回时,它释放锁。然后
f()
获取锁并调用
等待()
。没有人唤醒它,并且
f()
只是继续等待。这不是死锁;任何线程仍然可以调用
notify()
并唤醒
f()

注释行不可能导致循环。也许你的意思是死锁?是的。这是一个死锁。很抱歉我的英语不好。:)在添加
lock.unlock()之后,我的代码仍然存在死锁
.qaq当您可能完全丢失信号时。您可能应该在每行添加一些带有
endl
cout
语句。我打赌是“信号”线程在等待的线程之前运行。您可以尝试在启动两个线程之间休眠,以尝试并保证线程的顺序execution@KevinAnderson--不幸的是,插入I/O操作有时会改变时间,以至于最终隐藏了问题。这并不能解决问题。如果
g()
f()之前运行
然后
f()
将挂起,因为没有人将其唤醒。在布尔值上循环可避免虚假唤醒。它无法避免锁逻辑问题。@PeteBecker
f()
将如何挂起?while循环将检测到
g()
已运行before@PeteBecker在这种情况下,将条件与条件变量关联是同步的关键之一。
f()
将如何挂起?哎呀,对不起;太激进了。您是对的,布尔值将跳过对
wait()
的调用。
// Manual unlocking is done before notifying, to avoid waking up
// the waiting thread only to block again (see notify_one for details)
lk.unlock();
cv.notify_one();
void g() {
    std::unique_lock<std::mutex>  lock( mtx );
    std::this_thread::sleep_for( std::chrono::seconds(1) );
    lock.unlock();
    cv.notify_one();
}