Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

std::unique_lock - Cannot lock twice?

278 views
Skip to first unread message

Christopher

unread,
Mar 8, 2017, 5:57:18 PM3/8/17
to
I debugged an application to the following scenario:


#include <mutex>

std::mutex g_mutex;

int main()
{

std::unique_lock<std::mutex> lock(g_mutex);
lock.release();
lock.lock();
lock.release();
}


This throws on the second attempt to lock.
I thought the difference between unique lock and lock guard was that unique lock allowed manually locking and unlocking. We cannot lock it twice?

Chris Vine

unread,
Mar 8, 2017, 7:10:08 PM3/8/17
to
You want lock.unlock(), not lock.release(). With
std::unique_lock::release(), the mutex remains locked after the call
(the unique_lock just ceases to manage/own it).

nan dhan

unread,
Jun 8, 2023, 10:05:25 AM6/8/23
to
You have to use lock.unlock() instead of release(). Because release breaks the association of the mutex and not unlocks it.. so using unlock instead of release should solve.

Chris M. Thomasson

unread,
Jun 8, 2023, 3:12:06 PM6/8/23
to
On 6/8/2023 7:05 AM, nan dhan wrote:
> On Thursday, March 9, 2017 at 1:10:08 AM UTC+1, Chris Vine wrote:
>> On Wed, 8 Mar 2017 14:57:09 -0800 (PST)
>> Christopher <christo...@gmail.com> wrote:
>>> I debugged an application to the following scenario:
>>>
>>>
>>> #include <mutex>
>>>
>>> std::mutex g_mutex;
>>>
>>> int main()
>>> {
>>>
>>> std::unique_lock<std::mutex> lock(g_mutex);


_________________________
>>> lock.release();
>>> lock.lock();
>>> lock.release();
>>> }
_________________________

lock.unlock();
lock.lock();
lock.unlock();

?

Chris M. Thomasson

unread,
Jun 9, 2023, 8:47:05 PM6/9/23
to
On 6/8/2023 12:11 PM, Chris M. Thomasson wrote:
> On 6/8/2023 7:05 AM, nan dhan wrote:
>> On Thursday, March 9, 2017 at 1:10:08 AM UTC+1, Chris Vine wrote:
>>> On Wed, 8 Mar 2017 14:57:09 -0800 (PST)
>>> Christopher <christo...@gmail.com> wrote:
>>>> I debugged an application to the following scenario:
>>>>
>>>>
>>>> #include <mutex>
>>>>
>>>> std::mutex g_mutex;
>>>>
>>>> int main()
>>>> {
>>>>
>>>> std::unique_lock<std::mutex> lock(g_mutex);
>
>
> _________________________
>>>> lock.release();
>>>> lock.lock();
>>>> lock.release();
>>>> }
> _________________________
>
> lock.unlock();
> lock.lock();
> lock.unlock();
[...]

No! Shit man. Wait a minute. Self SLAP!!!!!

std::unique_lock<std::mutex> lock(g_mutex); --> LOCK

lock.unlock(); --> UNLOCK
lock.lock(); --> LOCK
lock.unlock(); --> UNLOCK

You need another lock _before_ that dtor of:

std::unique_lock<std::mutex> lock(g_mutex);

automatically unlocks! God damn it!

Chris M. Thomasson

unread,
Jun 9, 2023, 8:49:21 PM6/9/23
to
On 6/8/2023 12:11 PM, Chris M. Thomasson wrote:
> On 6/8/2023 7:05 AM, nan dhan wrote:
>> On Thursday, March 9, 2017 at 1:10:08 AM UTC+1, Chris Vine wrote:
>>> On Wed, 8 Mar 2017 14:57:09 -0800 (PST)
>>> Christopher <christo...@gmail.com> wrote:
>>>> I debugged an application to the following scenario:
>>>>
>>>>
>>>> #include <mutex>
>>>>
>>>> std::mutex g_mutex;
>>>>
>>>> int main()
>>>> {
>>>>
>>>> std::unique_lock<std::mutex> lock(g_mutex);
>
>
> _________________________
>>>> lock.release();
>>>> lock.lock();
>>>> lock.release();
>>>> }
> _________________________

^^^^^^^^^^^^

The dtor of the damn lock will unlock the mutex. The mutex needs to be
in a locked state before the scope goes out and unlocks it itself!

Sorry!

Ralf Fassel

unread,
Jun 14, 2023, 11:30:45 AM6/14/23
to
* "Chris M. Thomasson" <chris.m.t...@gmail.com>
| std::unique_lock<std::mutex> lock(g_mutex); --> LOCK
>
| lock.unlock(); --> UNLOCK
| lock.lock(); --> LOCK
| lock.unlock(); --> UNLOCK
>
| You need another lock _before_ that dtor of:

I don't think this is true:

https://en.cppreference.com/w/cpp/thread/unique_lock/%7Eunique_lock

~unique_lock();

Destroys the lock. If *this has an associated mutex and has acquired
ownership of it, the mutex is unlocked.

Note the conditional on unlocking the mutex in the DTOR.

R'

Chris M. Thomasson

unread,
Jun 14, 2023, 5:50:23 PM6/14/23
to
The release can be fairly dangerous.

{
std::unique_lock<std::mutex> lock(g_mutex);
// foo bar baz
}

The mutex gets locked, and automatically unlocked at the end of the
scope, right? Be very careful when using release...

Chris M. Thomasson

unread,
Jun 14, 2023, 5:52:50 PM6/14/23
to
I mistook release() for an unlock(). This can open a can of worms.
Actually, not exactly sure why unique_lock would even have a release
such that the dtor does not automatically unlock it. Sounds like a
nightmare deadlock waiting to happen.

Chris M. Thomasson

unread,
Jun 14, 2023, 6:02:26 PM6/14/23
to
On 6/14/2023 8:30 AM, Ralf Fassel wrote:
Yes. The damn acquire/release vs lock/unlock got me confused. Thanks for
the heads up Ralf!

Fwiw, I have had to use code where acquire and release actually meant
lock and unlock the mutex. Not alter the binding of the RAII object to
the underlying mutex itself!

ARGH!!!!

Sorry.

Bonita Montero

unread,
Jun 15, 2023, 1:07:57 PM6/15/23
to
Aside from that you've to use unlock() and not release():
unlock() releases ownership so you are unable to re-lock
the mutex.

Chris M. Thomasson

unread,
Jun 15, 2023, 10:24:18 PM6/15/23
to
what about a hand off algorithm. Pass the buck?

A has a reference, hands off to B, now A is null. B is current in a
single atomic operation. On and on...

https://youtu.be/oRrlRbGT-LU

;^)
0 new messages