条件变量卡在等待中

时间:2018-10-18 04:22:51

标签: c++ multithreading c++11 condition-variable

如果条件变量在worker_thread中被通知,为什么它一直处于等待状态?我在这里想念什么?

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

std::mutex m;
std::condition_variable cv;

void worker_thread()
{
    cv.notify_one();
}

int main()
{
    std::thread worker(worker_thread);

    std::cout << "Start waiting..." << std::endl;
    std::unique_lock<std::mutex> lk(m);
    cv.wait(lk);
    std::cout << "Finished waiting..." << std::endl;

    worker.join();

    getchar();
}

3 个答案:

答案 0 :(得分:1)

notify_one将取消阻塞一个正在等待的线程。如果没有等待线程,则什么也不会发生。 <img src="ftp://username:password@my_ftp_ip_address/Images/imagename.jpg"/>的状态无法记住等待时应通知多少个线程。

答案 1 :(得分:1)

您的问题是)仅唤醒当前正在等待的线程。 cv.notify_one()不记得您已通知它,后来有人来等待。

您的工作线程超出了您的主线程。因此,通知发生在主线程之前。

这只是您真正问题的征兆;您使用的条件变量错误。除非极其高级地使用,否则条件变量的所有使用都应为三重。

  1. 一个cv

  2. 一个std::condition_variable

  3. 有效载荷。

您的代码缺少有效载荷。

要发出信号,您:

std::mutex

听你的话

std::unique_lock<std::mutex> l(m);
payload = /* move it to a 'set' or 'non-empty' state */;
cv.notify_one(); // or all

std::unique_lock<std::mutex> l(m); cv.wait(l, [&]{ return /* payload is in a set or non-empty state */; }); // while locked, consume one "unit" of payload from the payload. 等有较小的变化。

遵循这种货物崇拜模式很重要,因为它避免了许多陷阱。通知后,它会处理两种虚假的唤醒。

您的代码缺少有效负载。因此,您的代码很容易受到等待线程(超出信号线程)和伪造唤醒的影响。

请注意,强烈建议您不要在这里“聪明”。例如,确定“我将使用原子变量以避免在发信号时使用互斥体”实际上是行不通的。要么教条地遵循上述方法,要么花几个月的时间来充分学习C ++的线程和内存模型,以便即兴创作。

答案 2 :(得分:-1)

例如,没有像Windows API这样的状态。您的问题是新线程在typeid之前到达A::Fields,然后您一无所获。您可以像这样模拟状态:

B::Fields