Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::lock_guard() for a locked std::mutex

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?

like image 575
marius.de Avatar asked Jul 30 '14 09:07

marius.de


People also ask

How does STD lock_guard work?

The point of lock_guard is just to make locking and unlocking the mutex easier for you. For example, if you manually lock / unlock , but your function throws an exception somewhere in the middle, it will never reach the unlock statement.

What is the difference between unique_lock and lock_guard?

A lock_guard always holds a lock from its construction to its destruction. A unique_lock can be created without immediately locking, can unlock at any point in its existence, and can transfer ownership of the lock from one instance to another.

Does unique_lock automatically lock?

@Prab, just to give the explanation: unique_lock() is automatically released when the destructor is called meaning it is exception safe and that it automatically unlocks when you leave scope.

Are lock guards deprecated?

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.


2 Answers

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).

like image 109
vladon Avatar answered Sep 21 '22 12:09

vladon


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

like image 29
RamblingMad Avatar answered Sep 22 '22 12:09

RamblingMad