【问题标题】:Multiple std::condition_variable notification to running thread using notify_one()使用 notify_one() 向正在运行的线程发出多个 std::condition_variable 通知
【发布时间】:2016-12-23 08:54:27
【问题描述】:

我正在尝试使用 std::condition_variable 从另一个线程(主线程)向正在运行的线程发送多个通知。发送一次有效,但第二次或多次发送似乎不起作用。这就是我所做的(没有实际事件的不必要细节):

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <future>

bool keep_running=true;
bool condition_reached=false;
std::mutex cond_mtx;
std::condition_variable cond;

void thread_waiting_to_be_notified(){
    while(keep_running){
        std::unique_lock<std::mutex> lk(cond_mtx);
        cond.wait(lk,[]()->bool{return condition_reached;});
        std::cout << "got notitication" << std::endl;
        condition_reached=false;
   }
}

void some_event(){
/*some event happens here*/
}

void another_event(){
/*another event happens here*/
}

int main(){
    std::thread thr(thread_waiting_to_be_notified);

    some_event();//first event
    std::cout << "some event happened" << std::endl;
    condition_reached=true;
    cond.notify_one();

    another_event();//second event
    std::cout << "another event happened" << std::endl; 
    condition_reached=true;
    cond.notify_one();
    keep_running=false;
    thr.join();

     return 0;
}

我得到的输出

some event happened
another event happened
got notitication

不过,我希望

some event happened
another event happened
got notitication
got notitication

任何建议将不胜感激。

【问题讨论】:

  • 也许你可以清理你的代码使其可读..
  • 您需要一个事件队列或一个原子计数器。条件变量不记得它被通知了多少次。如果线程在事件之间没有唤醒并重置条件变量,则第二次通知将无效。
  • 基本上,你需要atomic&lt;int&gt; condition_counter;而不是atomic&lt;int&gt; condition_counter;
  • @IlyaPopov 谢谢...刚刚检查过...有效!

标签: multithreading c++11 condition-variable


【解决方案1】:

尝试在后面插入lk.unlock();

condition_reached=false;

【讨论】:

  • 刚刚注意到一些有趣的事情。如果函数 another_event() 的处理时间超过 1 ns(纳秒),那么我会得到预期的结果......即使没有 lk.unlock()......我使用 std 在 another_event() 函数上稍作睡眠测试了这一点::this_thread::sleep_for(1ns);但是实际功能比 .... 花费的时间要短得多,所以我仍然会说它的不可预测的行为
猜你喜欢
  • 2018-06-24
  • 2015-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-19
相关资源
最近更新 更多