我更喜欢使用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
}
答案 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
的新值。