如果condition_variable::wait_for-delay参数在等待过程中发生更改,该怎么办


与基于时间的计时器相比,我更喜欢使用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
}

正如您在wait_forr()方法的规范中所看到的,延迟间隔被指定为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()的线程可以观察到参数的任何更改。

事实上,这里唯一的排序是释放和重新获取底层互斥体的间接结果。但是,请注意,只有在指定的超时到期后才会发生这种情况。因此,另一个线程对延迟参数所做的任何更改都将按顺序排列,并且执行wait_for()调用的线程将无法观察到。

请注意,如果所讨论的线程正在执行除锁定互斥锁和执行wait_for()之外的其他操作,除非主执行线程显式地执行将其更改排序为相对于其他线程的delay的操作,否则不能保证其他线程始终遵守delay的新值。

最新更新