14

Basically, the title is self-explanatory. I use it in following way:

  • The code is in Objective-C++.
  • Objective-C classes make concurrent calls to different purpose functions.
  • I use std::mutex to lock and unlock std::vector<T> editing option across entire class, as C++ std containers are not thread safe.
Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
ashvardanian
  • 424
  • 1
  • 6
  • 17

2 Answers2

23

Using lock_guard automatically unlocks the mutex again when it goes out of scope. That makes it impossible to forget to unlock it, when returning, or when an exception is thrown. You should always prefer to use lock_guard or unique_lock instead of using mutex::lock(). See http://kayari.org/cxx/antipatterns.html#locking-mutex

lock_guard is an example of an RAII or SBRM type.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
1

The std::lock_guard is only used for two purposes:

  1. Automate mutex unlock during destruction (no need to call .unlock()).
  2. Allow simultaneous lock of multiple mutexes to overcome deadlock problem.

For the last use case you will need std::adopt_lock flag:

std::lock(mutex_one, mutex_two);
std::lock_guard<std::mutex> lockPurposeOne(mutex_one, std::adopt_lock);
std::lock_guard<std::mutex> lockPurposeTwo(mutex_two, std::adopt_lock);

On the other hand, you will need allocate yet another class instance for the guard every time you need to lock the mutex, as std::lock_guard has no member functions. If you need guard with unlocking functionality take a look at std::unique_lock class. You may also consider using std::shared_lock for parallel reading of your vector.

You may notice, that std::shared_lock class is commented in header files and will be only accessible with C++17. According to header file you can use std::shared_timed_mutex, but when you will try to build the app it will fail, as Apple had updated the header files, but not the libc++ itself.

So for Objective-C app it may be more convenient to use GCD, allocate a couple of queue for all your C++ containers at the same time and put semaphores where needed. Take a look at this excellent comparison.

Community
  • 1
  • 1
ashvardanian
  • 424
  • 1
  • 6
  • 17
  • What does _"you will need allocate yet another class instance for the guard every time you need to lock the mutex"_ mean? You make it sound like `lock_guard` is bad. – Jonathan Wakely Jul 12 '16 at 23:33
  • Its not bad if you need it. But if you build the app in the way, that deadlock will not be possible - you don't need it. – ashvardanian Jul 13 '16 at 00:03