Replace boost::timed_wait() with std in c++17

85 Views Asked by At

I have a condition variable std::condition_variable my_cond;

I want to be able to replace boost::timed_wait() with an std equivalent one.

If the previously mentioned condition variable was a boost one, then I would use the boost version of timed_wait() like this: cond_.timed_wait(lock,timeout);

where lock is std::scoped_lock lock(mutex_); and timeout is a time that is performed with boost::chrono.

boost:chrono, boost locks and boost mutexes have been replaced with their std analogues. I have yet to find an alternative to timed_wait().

I try to find a function belonging to std, where it receives the lock as the first parameter and an std::chrono type time as a second parameter. Looking at the documentation of the condition_variable::wait here: https://en.cppreference.com/w/cpp/thread/condition_variable/wait

I don't see an overloaded wait function where the second argument is a time type.

Is this conversion from boost::timed_wait() to std::wait() possible?

EDIT: After trying users' Tony Salimi and Howard Hinnant suggestions, unofrtunately i get an error message. This is the error message:

error: no matching function for call to 
std::condition_variable::wait_for(std::scoped_lock<std::mutex>&, const std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int, std::ratio<1, 1000000000> > >&)’

This is the line that the error is given:

if(!my_cond.wait_for(lock,timeout))

timeout is: auto const timeout = std::chrono::system_clock::now() + std::chrono::milliseconds( ms );

lock is: std::scoped_lock lock(mutex_); where mutex_ is mutable std::mutex mutex_;

1

There are 1 best solutions below

3
Howard Hinnant On

For boost condition_variable::timed_wait is overloaded on waiting for a time duration, and waiting until a time point. And it isn't clear which overload you are using.

In std these functions have slightly different names instead of being overloaded on the same name:

  • Waiting for a time duration maps to wait_for.
  • Waiting until a time point maps to wait_until.

See the "see also" section of the page you linked to: https://en.cppreference.com/w/cpp/thread/condition_variable/wait

For wait_for you can use any std::chrono::duration instantiation (duration is a class template). Common examples are std::chrono::milliseconds and std::chrono::seconds.

For wait_until you can use any std::chrono::time_point instantiation for which std::chrono::time_point::clock meets the Cpp17Clock requirements. Common examples are std::chrono::steady_clock::time_point and std::chrono::system_clock::time_point.

Update

std::condition_variable waits on a std::unique_lock, not a std::scoped_lock.

The history of the names of the locks is a bit tortured.

Originally there was boost::scoped_lock. During the standardization process, functionality changed, and so did the names. std::lock_guard and std::unique_lock were introduced in C++11. Neither was identical to boost::scoped_lock, and the different names helped imply that.

Then in C++17, std::scoped_lock was introduced which added new functionality, and is even more different from boost::scoped_lock.

std::unique_lock is the lock used for all condition_variable operations. It alone has the semantics that it can hold ownership in a non-scoped manner. That is, it has unlock(). This is consistent with the semantics of condition_variable::wait which unlocks the lock upon waiting, and re-locks it when returning from the wait.