7

std::condition_variable in use as the following:

std::condition_variable cv;
...
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{return processed;});

Seems to me to have an interesting problem. unique_lock could be deferred, it could have been swapped away. It could have numerous other reasons by code design and not necessarily bad mistakes that it is not actually locked. eg.

std::unique_lock<std::mutex> lk(m, std::try_to_lock_t); // or  std::defer_lock_t
// Try to lock fails.
cv.wait(lk, []{return processed;});

Why not enforce a locked situation by making std::conditional_variable work with lock_guard instead? Then you would be very hard pressed to get into this situation. In fact the only way would be to do this:

// m is not already locked
std::lock_gaurd<std::mutex> lk(m, std::adopt_lock);
cv.wait(lk, []{return processed;});

Rather than the multitude of ways available in unique_lock. Is there a technical reason to use unique_lock over lock_guard for a condition_variable?

Fantastic Mr Fox
  • 32,495
  • 27
  • 95
  • 175
  • The question title is exactly the question asked here. The accepted answer covers all bases (even more than the current answers here). The OP does indeed make it about `mutex` vs `unique_lock`, but the highest voted answer covers so much more, including a dedicated paragraph on why not `lock_guard`. – rubenvb Aug 10 '18 at 08:21
  • @rubenvb You are absolutely right. I must have missed that paragraph when i read the answer. Thanks for the help. – Fantastic Mr Fox Aug 10 '18 at 08:24
  • No problem. Duplicates primarily serve to direct users and visitors to good comprehensive answers. It's not a slap on the wrist or anything. Just a [303 See other](https://en.wikipedia.org/wiki/HTTP_303). – rubenvb Aug 10 '18 at 08:27

2 Answers2

6

The condition variable needs to be able to lock and unlock the mutex, lock_guard doesn't allow this. lock_guard also doesn't allow access to the mutex itself which most condition variable implementations probably require.

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
1

lock_guard and unique_lock are pretty similar. However a lock_guard locks on construction and unlocks on destruction. Using condition_variable the mutex needs to be possible locked and unlocked multiple times.

You can basically use unique_locks everywhere, however they impose more overhead than a simple lock_guard.

std::condition_variable works only with std::unique_lock; this restriction allows for maximal efficiency on some platforms. std::condition_variable_any provides a condition variable that works with any BasicLockable object, such as std::shared_lock.

taken from cppreference

rmm19433
  • 280
  • 2
  • 10