isocpp / isocpp/CppCoreGuidelines

CP guidelines for locking/unlocking mutexes

Open
#553 1 comment 1 reaction 1 assignee View on GitHub

@hsutter is already working on this.

Since Apr 4, 2016.

review
Dominant language
CSS
Stars
45.3k
Forks
5.6k
PR merge metrics
No merged PRs in 30d

Description

This is taken from my own website: http://kayari.org/cxx/antipatterns.html#locking-mutex (adjusted to link to the RAII section of the guidelines instead of linking to Wikipedia's RAII page).

While I expect SG1 people to suggest guidelines for higher-level P&C techniques, C++14 doesn't include those, so the guidelines should cover basic use of std::mutex.

Locking and unlocking a std::mutex

This is always wrong:

  std::mutex mtx;

  void func()
  {
    mtx.lock();
    // do things
    mtx.unlock();
  }

It should always be done using one of the RAII scoped lock types
such as lock_guard or unique_lock e.g.

  std::mutex mtx;

  void func()
  {
    std::lock_guard<std::mutex> lock(mtx);
    // do things
  }

Using a scoped lock is exception-safe, you cannot forget to unlock the mutex
if you return early, and it takes fewer lines of code.

Recommendation: always use a scoped lock object to lock and unlock a mutex

Be careful that you don't forget to give a scoped lock variable a name!
This will compile, but doesn't do what you expect:

  std::mutex mtx;

  void func()
  {
    std::unique_lock<std::mutex> (mtx);  // OOPS!
    // do things, but the mutex is not locked!
  }

This default-constructs a unique_lock object called mtx, which has nothing
to do with the global mtx object (the parentheses around (mtx) are
redundant and so it's equivalent to simply std::unique_lock<std::mutex> mtx;).

A similar mistake can happen using braces instead of parentheses:

  std::mutex mtx;

  void func()
  {
    std::unique_lock<std::mutex> {mtx};  // OOPS!
    // do things, but the mutex is not locked!
  }

This does lock the global mutex mtx, but it does so in the constructor
of a temporary unique_lock which immediately goes away and unlocks the
mutex again.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.