TLDR:
Pedantically, you need to call pthread_mutex_destroy()
for every initialized mutex if you need to be absolutely certain no resources are leaked under any circumstances.
In reality, most times it won't matter, either because there's no way to call pthread_mutex_destroy()
, or you know your implementation doesn't use dynamic memory in mutexes, or the process is exiting and you don't really care if it leaks.
Full Answer:
To expand on @KamilCuk's answer, from his link to POSIX's documentation for pthread_mutex_destroy()
:
An implementation may cause pthread_mutex_destroy()
to set the object referenced by mutex to an invalid value.
One way to do that is for an implementation to call free()
for mutex resources allocated during the creation and use of the mutex. Nothing rules out an implementation using dynamic allocation for any mutex - an implementation is even free under the "as-if" rules of C's abstract machine to use a PTHREAD_MUTEX_INITIALIZER
that performs dynamic allocation even for static initialization of static variables at file scope, where normally C would not allow something like
static some_type *var = malloc( sizeof( *var ) );
(If C++ can create new
objects at file scope, it'd be almost trivial for a C implementation to use something similar internally, even if it flags your attempts to do so as C errors.)
So pedantically, if you want to strictly avoid leaking any memory, pthread_mutex_destroy()
must be called for every mutex you initialize.
The reality is different.
First, many (most?) of the time you will use a mutex, there will be no easy way to destroy it. For example, it can be a static
with limited scope deep inside a function used to protect a critical section of code - there's no way to reliably call pthread_mutex_destroy()
on such a mutex. Even if you register an atexit()
function to destroy the mutex, that function won't be called in all ways a process can exit.
Second, most implementation of standard mutexes don't allocate any dynamic memory.
Third, many (most?) uses of mutexes are meant to exist for the life of the program - they only need to be destroyed if the program is exiting. And if the program is exiting, there's no functional impact if they're not destroyed.
But if you're creating struct
s dynamically and initializing mutexes in the struct
s with pthread_mutex_init()
, you really should run pthread_mutex_destroy()
on them when you free()
the struct
even if you know your use of your implementation's mutex doesn't do any dynamic allocation - someone might change the mutex to something more complex like an error-checking or robust mutex that might very well dynamically allocate memory on your implemenation, the code could be ported to another implementation, or the implementation itself could change. Get it right and don't open up that window for a completely unnecessary future bug.