2016-11-15 125 views
1
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,调用Init并等待B完全初始化,即使running_是true,也有时会挂起等待。这发生。任何帮助将不胜感激。notify_all没有唤醒等待线程

+0

'running_'是什么类型? 'bool'或'std :: atomic '? – ildjarn

+0

running_纯粹是bool,我曾尝试将它声明为std :: atomic ,仍然不起作用 – user2260241

+0

@ user2260241在C++中,默认情况下没有什么是保证原子的,甚至不是'bool'。您必须同步对'running_'的访问,否则您将进行数据竞赛。 – Snps

回答

1

std::condition_variable::wait(lock, pred)是基本相同

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

如果线程设置running_true并调用谓词检查的时间之间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; 
    } 
} 
+0

谢谢,bro.I想通了,就像你说的那样,它有一个在谓词被检查但在等待被调用之前的时间。 – user2260241