Non-recursive use of a mutex

I read this answer on SO:

Because a recursive mutex has a sense of ownership, the stream that captures the mutex must be the same stream that releases the mutex. In the case of non-recursive mutexes, there is no sense of ownership, and any thread can usually release a mutex no matter which thread originally received the mutex.

I am confused by the last statement. Can one thread lock a mutex and another thread unlock this mutex? I thought the same thread should be the only one capable of unlocking the mutex? Or is there any specific mutex that allows this? Hope someone can clarify.

+3
source share
3 answers

Non-recursive mutex

Most mutexes are (or at least should be) non-recursive. A mutex is an object that can be received or released atomically, which allows you to transfer data that is distributed between several streams, which must be protected from race conditions, data distortion and other unpleasant things.

One mutex should ever be received once by one thread in the same call chain. Trying to get (or hold) the same mutex twice within the same thread context should be considered an invalid script and should be handled accordingly (usually through ASSERT, because you are breaking the fundamental contract of your code).

Fractal Mutex

. , , , .

. , , . , , .

, .


, , . , , :

Thread 1

    Acquire mutex A
    // Modify or read shared data
    Release mutex A

Thread 2

    Attempt to acquire mutex A
    Block as thread 1 has mutex A
    When thread 1 has released mutex A, acquire it
    // Modify or read shared data
    Release mutex A

, , (, A B). , :

Thread 1

    Acquire mutex A
    // Access some data...

*** Context switch to thread 2 ***

Thread 2

    Acquire mutex B
    // Access some data

*** Context switch to thread 1 ***

    Attempt to acquire mutex B
    Wait for thread 2 to release mutex B

*** Context switch to thread 2 ***

    Attempt to acquire mutex A
    Wait for thread 1 to release mutex A

*** DEADLOCK ***

, , - ABBA.

, , (, A, B).

+6

( = , = ). , .

+1

, . man linux pthreads:

PTHREAD_MUTEX_NORMAL, . .         , , , , undefined .

PTHREAD_MUTEX_ERRORCHECK, . ,        , . , , , ,        .

PTHREAD_MUTEX_RECURSIVE, .        mutex , . , , .         , , . ,         . , , , ,        .

If the mutex type is PTHREAD_MUTEX_DEFAULT, an attempt to recursively block the mutex results in undefined behavior. Attempting to unlock mutexes if it was not blocked by the calling thread leads to undefined behavior. Attempting to unlock a mutex if it is not locked results in undefined behavior.

+1
source

Source: https://habr.com/ru/post/1734186/


All Articles