【问题标题】:notify_all does not wake up wait threadnotify_all 不唤醒等待线程
【发布时间】:2016-11-15 16:01:20
【问题描述】:
DBThread::DBThread() : running_(false)
{

}

DBThread::~DBThread()
{
    if (thread_)
    {
        thread_->join();
    }
}

void DBThread::Init()
{
    thread_ = std::make_shared<std::thread>(std::bind(&DBThread::Run, this));
    std::unique_lock<std::mutex> lock(mutex_);
    cv_.wait(lock, [&] {return running_; });
    std::cout << "Init success";
}

void DBThread::AddTask(std::shared_ptr<Delegate> task)
{
    std::lock_guard<std::mutex> lock(mutex_);
    task_queue_.push(task);
}

void DBThread::Run()
{
    running_ = true;
    cv_.notify_all();
    while (true)
    {
        std::unique_lock<std::mutex> lock(mutex_);
        cv_.wait(lock, [&] {return !task_queue_.empty(); });
        std::cout << "run task" << std::endl;
    }
}

我有两个线程,我们将其命名为 A 和 B,A 调用 Init 并等待 B 完全初始化,即使 running_ 为真,A 有时也会等待。知道为什么会发生这种情况。任何帮助将不胜感激。

【问题讨论】:

  • running_ 是什么类型? boolstd::atomic&lt;bool&gt;?
  • running_ 纯粹是 bool,我试过将它声明为 std::atomic,还是不行
  • @user2260241 默认情况下,C++ 中的任何内容都不能保证是原子的,甚至 bool 也不保证。您必须同步对running_的访问,否则您将遇到数据竞争。

标签: c++ multithreading c++11


【解决方案1】:

std::condition_variable::wait(lock, pred)基本一样

while (!pred()) {
    wait(lock);
}

如果线程将running_ 设置为true 并在检查谓词之间但在调用wait 之前调用notify_all(),则通知将丢失,等待将等待直到另一个通知到来.最简单的修复方法是:

void DBThread::Run()
{
    std::unique_lock<std::mutex> lock(mutex_);
    running_ = true;
    cv_.notify_all();
    while (true)
    {
        cv_.wait(lock, [&] {return !task_queue_.empty(); });
        std::cout << "run task" << std::endl;
    }
}

【讨论】:

  • 谢谢,兄弟。我想通了,就像你说的,它在检查谓词之间有一个时间,但在调用等待之前。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-31
  • 1970-01-01
  • 2021-06-10
  • 2019-12-04
  • 1970-01-01
  • 2021-01-05
  • 2012-03-18
相关资源
最近更新 更多