缺少条件变量的通知

时间:2017-04-01 21:02:44

标签: c++ multithreading concurrency c++14

在下面的代码中,我将有一个工作线程,它将具有一个主要状态 - 已启动。开始不是线程启动状态,而是阻塞调用最终返回的状态,我已经用随机延迟和注释替换了它。

我在这里尝试的是首先尽快启动工作线程,阻止它阻止呼叫,同时保持started = false直到它没有返回。一旦它返回,我就会started = true并通知main线程的无限循环以启动另一个线程并再次等待。以前的工作线程现在可以继续执行其工作。然后重复这个过程。 新线程的启动必须等待前一个线程的START状态。

但在我之前的question中,有人提到了这个 -

  

如果在cv.wait运行通知之前调用了cv.notify_one   将被遗漏。在提供的代码中,它很可能会。

目前我尝试以各种方式手动测试它,但无法收到错误,一切都按照我的想法运行。所以我想知道在什么情况下它实际上会错过它,无论如何使其重现,以及如果它是一个问题如何实际解决它?

#include <iostream>
#include <string>
#include <mutex>
#include <condition_variable>
#include <future>
#include <atomic>
#include <chrono>
#include <thread>
#include <random>

std::mt19937_64 eng{std::random_device{}()};
std::uniform_int_distribution<> dist{100, 2000};

std::mutex m;
std::condition_variable cv;
bool started = false;
std::atomic<int> count(0);

void worker_thread()
{
    std::unique_lock<std::mutex> lk(m);
    int local_cnt = count++;

    // some blocking call represented by random delay
    std::this_thread::sleep_for(std::chrono::milliseconds{dist(eng)});
    std::cerr << "Enter Accept: " << local_cnt << "\n";

    started = true;
    lk.unlock();
    cv.notify_one(); // notify to launch other threads

    // complete other work here
    std::this_thread::sleep_for(std::chrono::milliseconds{dist(eng) + 2000});
    std::cerr << "Exit Accept: " << local_cnt << "\n";
}

int main()
{
    while(1){
        std::thread(worker_thread).detach();
        std::unique_lock<std::mutex> lk(m);
        cv.wait(lk, []{return started;});
        started = false;
    }
}

0 个答案:

没有答案