6

I am new to C++11 threading.

The following piece of code should be executed only by the first thread.

The other threads (which might race with the first thread) should not enter the locked code area (that's why the std::try_lock() is there).

std::mutex mu;

// now ensure this will get called only once per event
if (std::try_lock(mu) != -1)
{ 
    return;
}

{
    std::lock_guard<std::mutex> guard(mu);
    // critical section

} // mutex will be unlocked here        

(Outside from writing my own lock_guard) Is there a way to use a similar & standard std::lock_guard variant, but which will take my !locked! mutex (effect of std::try_lock() above) and simply unlock it when the d-tor of that guard will be called?

Manumerous
  • 455
  • 6
  • 21
marius.de
  • 107
  • 1
  • 7

2 Answers2

10

Use this:

// now ensure this will get called only once per event
if (_mutex.try_lock())
{ 
    std::lock_guard<std::mutex> guard(_mutex, std::adopt_lock);

    // critical section
} // mutex will be unlocked here

Update And don't use variable names starting with underscore (as _mutex).

vladon
  • 8,158
  • 2
  • 47
  • 91
  • Why not `use variable names starting with underscore`? [What are the rules about using an underscore in a C++ identifier?](https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) – Evandro Coan Apr 20 '21 at 16:52
2

Have a look at this

and this

From this info you can see that if you specify a second parameter like this std::lock_guard<std::mutex> guard(_mutex, std::try_to_lock) the behaviour is changed to act like std::try_lock rather than std::lock

RamblingMad
  • 5,332
  • 2
  • 24
  • 48
  • 3
    Almost correct. lock_guard doesn't take a try_to_lock_t. It is however possible to use the existing try_lock in the ops code and then construct a lock_guard using std::adopt_lock to tell it that the mutex is already locked. – John5342 Jul 30 '14 at 15:46