使用condition.wait()时出现死锁

时间:2019-06-18 17:55:24

标签: c++ multithreading mutex race-condition monitor

在此处找到代码:http://coliru.stacked-crooked.com/a/7942a18fe11ea544

我正在试验condition.wait,没有超时,发现自己陷入了僵局。我要执行的操作的要旨是坐在一个锁中,直到我确定已创建一个新文件为止。我将设置一个标志并通知线程,然后该线程将(在我的真实程序中)触发一个回调函数。在运行结束时,我想关闭所有线程。我将循环变量设置为false,然后通知一个,我认为这将取消阻塞线程。我是否误认为这会忽略谓词评估的内容?

有人可以建议一个更好的线程布局来纠正死锁吗? 谢谢。

#include <iostream>
#include <string>
#include <thread>
#include <chrono>
#include <atomic>
#include <mutex>
#include <condition_variable>

using namespace std::chrono_literals;
std::atomic_bool new_file_created_{false};
std::atomic_bool run_data_logger_{false};
std::condition_variable file_monitor_condition_;
std::mutex file_monitor_mutex_;
std::thread test_thread_;

void file_monitor_thread_func()
{
    using namespace std::chrono_literals;
    while (run_data_logger_)
    {
        std::unique_lock<std::mutex> lock(file_monitor_mutex_);
        file_monitor_condition_.wait(lock, [] { return new_file_created_.load(); });
        if (new_file_created_)
        {
            std::cout<< "New File Created" << std::endl;
            new_file_created_ = false;                       
            //do some stuff
        }
        else
        {}                
    }
}

void end_the_thread()
{
    std::cout << "Ending the Thread" << std::endl;
    run_data_logger_ = false;
    file_monitor_condition_.notify_one();
    if (test_thread_.joinable())
        test_thread_.join();

    std::cout << "Thread Ended" << std::endl;
}

void trigger_new_file()
{
   new_file_created_ = true;
   file_monitor_condition_.notify_one(); 
}

void start_the_thread()
{
    run_data_logger_ = true;
    test_thread_ = std::thread(file_monitor_thread_func);

    trigger_new_file();
}

int main()
{
    for (int j = 0; j<10; j++)
    {

        start_the_thread();
        std::this_thread::sleep_for(500ms);            
        end_the_thread();
    }
}

2 个答案:

答案 0 :(得分:3)

new_file_created_首次成为true之后,file_monitor_thread_func将其重置为false,然后循环并等待它再次变为true。但是没有人再次将其设置为true

答案 1 :(得分:0)

condition_variablemutex一起使用,这不是装饰性的功能。您似乎对

有印象
    std::unique_lock<std::mutex> lock(file_monitor_mutex_);

足以满足wait方法的先决条件;但是互斥锁从概念上讲只有在用于互斥时才有意义。您并没有使用它,因为互斥锁仅被锁定在file_monitor_thread_func内部,所以不能保证状态更改操作互斥。

您不正确使用监视器的一个明显迹象是,您觉得有必要使用原子对象,因为互斥(这是前提)保证可以使用普通对象。

根本无法将条件和原子对象组合在一起。它们属于不同的设计。