【问题标题】:missed signal in c++11 condition variableC ++ 11条件变量中的错过信号
【发布时间】:2017-02-18 01:59:00
【问题描述】:

我有点怀疑线程被唤醒和锁不可用

std::mutex mut; 
std::queue<data_chunk> data_queue;   
std::condition_variable data_cond;

void data_preparation_thread() {    
    while(more_data_to_prepare())    {        
        data_chunk const data=prepare_data();        
        std::lock_guard<std::mutex> lk(mut);        
        data_queue.push(data);                      
        data_cond.notify_one(); //mutex is still locked here      
    }
}

void data_processing_thread() {
    while(true)    {
        std::unique_lock<std::mutex> lk(mut); 
        data_cond.wait(lk,[]{return !data_queue.empty();}); //what if lk could not acquire the mutex.
        data_chunk data=data_queue.front();        
        data_queue.pop();        
        lk.unlock();
        process(data);
        if(is_last_chunk(data))
            break;
    }

}

在上面的示例中,data_preparation_thread() 将数据放入队列中,并在 condition_variable 上通知和线程等待。

我的问题,如果另一个线程醒来并发现关联的互斥锁仍然不可用,它会再次休眠。不是信号丢失的情况吗?

【问题讨论】:

    标签: multithreading c++11


    【解决方案1】:

    如果另一个线程醒来发现关联的互斥体仍然不可用,则再次休眠

    一旦它重新获得互斥体,它就会继续测试条件。

    条件变量通知本质上是条件可能已更改并需要重新评估的提示。可以有spurious wake-ups。代码等待条件变为真,而不是等待信号。

    【讨论】:

      【解决方案2】:

      条件变量上的“睡眠”(即等待信号)和互斥锁上的“睡眠”(即等待锁定它)是有区别的。

      如果线程从等待条件变量中醒来并且互斥锁仍处于锁定状态,则它开始等待互斥锁,直到它可以获取它然后检查条件(即谓词)。这与再次等待 condvar 不同,因此没有遗漏任何内容。它仍在等待检查条件是否为真,直到它获得互斥锁才能执行此操作。

      假设您在醒来时正确检查了条件(这是您传递给 condition_variable::wait 的谓词所做的),那么您将不会错过导致信号的事件。

      【讨论】:

        猜你喜欢
        • 2020-07-12
        • 1970-01-01
        • 2011-03-31
        • 1970-01-01
        • 1970-01-01
        • 2011-10-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多