Fuad
Fuad

Reputation: 1509

What happens if a thread in C tries to acquire a lock it already has?

So assuming 1 thread, the thread acquires a lock via:

pthread_mutex_lock(&lock);

then before unlocking, it again reaches a line that is:

pthread_mutex_lock(&lock);

Will the pthread library block the advancement of the thread, or will it recognize that the thread already holds the lock, thus letting it pass?

Upvotes: 3

Views: 4587

Answers (2)

The behaviour depends on the kind of the mutex. The POSIX standard says that recursive locking behaviour depends on the type of the lock

If a thread attempts to relock a mutex that it has already locked, pthread_mutex_lock() shall behave as described in the Relock column of the following table.

With the Relock column saying that

  • a mutex of type PTHREAD_MUTEX_NORMAL can deadlock
  • a mutex of type PTHREAD_MUTEX_ERRORCHECK shall return an error
  • a mutex of type PTHREAD_MUTEX_RECURSIVE will work as a recursive lock, that you must then unlock as many times as you locked it
  • a mutex of type PTHREAD_MUTEX_DEFAULT will have undefined behaviour, which actually means that if on that platform the default lock is of any of the previous 3 types, it will behave characteristically as in the columns above, and if it is some other type then the behaviour will be undefined.

Thus there is especially no point in testing a PTHREAD_MUTEX_DEFAULT lock to find out what the behaviour is.

And the Linux manuals pthread_mutex_lock(3) rephrases with the following:

If the mutex is already locked by the calling thread, the behavior of pthread_mutex_lock depends on the kind of the mutex. If the mutex is of the fast kind, the calling thread is suspended until the mutex is unlocked, thus effectively causing the calling thread to deadlock. If the mutex is of the error checking kind, pthread_mutex_lock returns immediately with the error code EDEADLK. If the mutex is of the recursive kind, pthread_mutex_lock succeeds and returns immediately, recording the number of times the calling thread has locked the mutex. An equal number of pthread_mutex_unlock operations must be performed before the mutex returns to the unlocked state.

In Linux according to the documentation, the default type is fast, but you cannot rely that to be portable.

Upvotes: 9

Florian Weimer
Florian Weimer

Reputation: 33704

POSIX supports many different mutex types in several variants. All use the same pthread_mutex_t type, so it is not possible to tell what pthread_mutex_lock does when re-locking a lock which has already been acquired by the current thread.

Common behaviors include:

  • A self-deadlock for a regular mutex (pthread_mutex_lock never returns).
  • An error for an error-checking mutex (pthread_mutex_lock returns with an error code).
  • The lock operation succeeds and one more unlock operation will be required before the lock becomes available to other threads for locking (a recursive mutex).

Mutex behavior can be selected when the mutex is created with pthread_mutex_init using attributes; see pthread_mutexattr_init. Some systems also offer non-standard initializers like the standard PTHREAD_MUTEX_INITIALIZER one which create different variants.

Upvotes: 0

Related Questions