如果condition_variable :: wait_for延迟参数在等待过程中发生变化怎么办?

时间:2017-01-25 16:47:56

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

我更喜欢使用condition_variable::wait_for作为基于计时器的计时器的计时器,因为我可以通过指定谓词来覆盖等待条件。所以我编写了一个测试程序来检查一旦等待进程已经开始,延迟持续时间是否会发生变化。 condition_variable::wait_for似乎忽略了更改,而是完全退出了等待过程。为什么是这样?我可以在等待过程中更改它吗?

enum STATE {START,STOP,NONE};

STATE  state ;
condition_variable cv;
mutex mu;
chrono::milliseconds delay;

void cv_wait_thread()
{
    {
        unique_lock<mutex> lock(mu);
        cv.wait(lock, [](){ return state == START; });
    }

    chrono::time_point<chrono::high_resolution_clock> start_time = chrono::high_resolution_clock::now();

    {
        unique_lock<mutex> lock(mu);
        cv.wait_for(lock, delay);       
    }

    auto diff = chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start_time);


    cout << "Conditional_wait:  "<< diff.count() << " milliseconds" << endl;

}


void main()
{
    thread thread1([](){ cv_wait_thread(); });

    state = NONE;   

    this_thread::sleep_for(chrono::seconds(1));

    delay = chrono::milliseconds(3000);

    state = START;
    cv.notify_all(); // ask thread to sleep for 3 sec

    this_thread::sleep_for(chrono::milliseconds(2000)); // let cv_wait thread start the wait process for at least 2 sec already

    delay = chrono::milliseconds(5000); // ask thread to correct and sleep for 5 sec instead

    cv.notify_all();

    thread1.join(); // thread prints 2000 milli
}

1 个答案:

答案 0 :(得分:4)

如您所见[{3}},延迟间隔指定为const参数:

template< class Rep, class Period >
std::cv_status wait_for( std::unique_lock<std::mutex>& lock,
                         const std::chrono::duration<Rep, Period>& rel_time);

此外,wait_for()的规范中没有任何内容表明正在执行wait_for()的线程可以观察到对参数的任何更改。

事实上,这里唯一的排序是释放和重新获取底层互斥锁的间接结果。但请注意,只有在指定的超时到期后 之后才会发生这种情况。因此,对另一个线程对delay参数所做的任何更改都将 排序,直到那个时间,并且执行{{1}的线程将无法观察到打电话。

注意,如果有问题的线程正在执行除锁定互斥锁和执行wait_for()之外的其他操作,除非主执行线程显式执行将其更改排序为wait_for()相对于另一个的内容线程,其他线程不保证会观察到delay的新值。