HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppCritical

std::lock_guard or std::scoped_lock?

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
scoped_locklock_guardstd

Problem

C++17 introduced a new lock class called std::scoped_lock.

Judging from the documentation it looks similar to the already existing std::lock_guard class.

What's the difference and when should I use it?

Solution

Late answer, and mostly in response to:

You can consider std::lock_guard deprecated.

For the common case that one needs to lock exactly one mutex, std::lock_guard has an API that is a little safer to use than scoped_lock.

For example:

{
   std::scoped_lock lock;  // protect this block
   ...
}


The above snippet is likely an accidental run-time error because it compiles and then does absolutely nothing. The coder probably meant:

{
   std::scoped_lock lock{mut};  // protect this block
   ...
}


Now it locks/unlocks mut.

If lock_guard was used in the two examples above instead, the first example is a compile-time error instead of a run-time error, and the second example has identical functionality as the version which uses scoped_lock.

So my advice is to use the simplest tool for the job:

-
lock_guard if you need to lock exactly 1 mutex for an entire scope.

-
scoped_lock if you need to lock a number of mutexes that is not exactly 1.

-
unique_lock if you need to unlock within the scope of the block (which includes use with a condition_variable).

This advice does not imply that scoped_lock should be redesigned to not accept 0 mutexes. There exist valid use cases where it is desirable for scoped_lock to accept variadic template parameter packs which may be empty. And the empty case should not lock anything.

And that's why lock_guard isn't deprecated. scoped_lock and unique_lock may be a superset of functionality of lock_guard, but that fact is a double-edged sword. Sometimes it is just as important what a type won't do (default construct in this case).

Code Snippets

{
   std::scoped_lock lock;  // protect this block
   ...
}
{
   std::scoped_lock lock{mut};  // protect this block
   ...
}

Context

Stack Overflow Q#43019598, score: 389

Revisions (0)

No revisions yet.