isocpp / isocpp/CppCoreGuidelines
CP guidelines for locking/unlocking mutexes
@hsutter is already working on this.
Since Apr 4, 2016.
- 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.