Reputation: 2244
I am following Advanced Linux Programming book.
Mutex can be initialized dynamically by Using the init function:
pthread_mutex_t theMutex;
pthread_mutex_init(&theMutex, NULL);
Mutex can be initialized statically by macro
pthread_mutex_t result = PTHREAD_MUTEX_INITIALIZER;
The book says that we have to call "pthread_mutex_destroy(&theMutex)" if we create mutex dynamically, mutex will be created in heap area so we have to delete it manually.
But if we create mutex statically the effect shall be equivalent to dynamic initialization by a call to pthread_mutex_init() with parameter attr specified as NULL, except that no error checks are performed.
I think with statically allocated mutexes, threads of the same program can only share it until their scope ends, but with dynamically allocated mutexes, threads of different program would be able to interact with the mutex.
Is my understanding correct? And if any other differences are there please mention it.
Upvotes: 3
Views: 9569
Reputation: 180151
Notwithstanding the age of this question, as long as it was autobumped, and given that I neither find the existing answers satisfactory nor find a good dupe target, I'll give it a go.
Mutex can be initialized dynamically by Using the init function [... or ...] statically by macro
Characterizing the initialization itself as static or dynamic is a poor choice of words, because those terms are more closely associated with storage allocation and duration. That is a distinct, albeit related consideration, and the question seems to mix the concepts, both here and further on. Moreover, some versions of POSIX qualify PTHREAD_MUTEX_INITIALIZER
as being applicable specifically to mutexes having static storage duration, remaining silent on whether it also can be used for those having automatic storage duration, whereas the current version omits that qualification. As far as I am aware, no pthreads implementation ever provided a PTHREAD_MUTEX_INITIALIZER
that did not work equally well for intialization of statically and automatically allocated mutexes.
The book says that we have to call "pthread_mutex_destroy(&theMutex)" if we create mutex dynamically mutex will be created in heap area so we have to delete it manually.
If I understand the book correctly, or at least that take on it, then there is a bit of a misunderstanding here, leading to a cart-preceding-horse situation. That storage for a mutex itself resides on the heap would be a consequence of dynamic allocation of storage for that mutex, not of "dynamic initialization" via pthread_mutex_init()
. The structure and semantics of the C language dictate that a dynamically-allocated mutex can be initialized only via that function, but it is not use of that function that makes the mutex dynamically allocated.
If the mutex is dynamically allocated then its storage indeed does need to be freed manually when no longer needed. If it also was initialized via pthread_mutex_init()
(as opposed to not being initialized at all) then it is at minimum good style to first destroy it via pthread_mutex_destroy()
, but that's a separate consideration. There is, however, a possibility that pthread_mutex_init()
dynamically allocates additional memory and stores a pointer to it in the mutex object. In that case, one would expect pthread_mutex_destroy()
to free that memory, and failure to call that function might, therefore, create a memory leak.
But if we create mutex statically the effect shall be equivalent to dynamic initialization by a call to pthread_mutex_init() with parameter attr specified as NULL, except that no error checks are performed.
This is the effect of initialization by use of PTHREAD_MUTEX_INITIALIZER
, not directly related to how the mutex was allocated. A mutex that is statically or automatically allocated can be initialized via either approach, so allocation type does not determine initialization style.
I think with statically allocated mutexes, threads of the same program can only share it until their scope ends, but with dynamically allocated mutexes, threads of different program would be able to interact with the mutex.
This is again mixing concepts. A mutex may be used during the parts of its lifetime when it has a valid value (and only then). Its lifetime is closely related to its allocation type, but has nothing to do with how it is initialized. As with objects of any other type, the lifetime of an automatically-allocated mutex ends when execution of the block to which its scope is tied terminates, but the lifetimes of mutexes allocated statically or dynamically are not tied to scope.
Within its lifetime, a mutex is valid between each successful initialization and the next subsequent use of pthread_mutex_destroy()
on it. All threads of all processes that have access to a given mutex can use it when it is valid. This is not related to allocation status. It is related to initialization style in that pthreads mutexes default to not being shared between processes, so those mutexes that were most recently initialized via PTHREAD_MUTEX_INITIALIZER
in fact will not be shared between processes.
That does not imply that an automatically- or statically-allocated
mutex cannot be shared among processes, as these can be (re)initialized via pthread_mutex_init()
in a manner that makes them process-shared. On the other hand, regardless of the nature of its allocation, (re)initialization via pthread_mutex_init()
does not automatically make a mutex process-shared. One needs to engage a mutex attributes object that specifies so if that's what one wants.
Is my understanding correct?
No. It seems overall rather mixed up, and it is outright wrong in several particulars. See above.
Upvotes: 2
Reputation: 209
Using PTHREAD_MUTEX_INITIALIZER
is not compulsory for a static mutex, but it is available. It sets a common group of default attributes for a mutex - there are a couple of other initializers for recursive and error check mutexes too, instead of the stock 'normal fast mutexes'. Think of it as simply assigning values to the members of the opaque pthread_mutex_t
struct.
pthread_mutex_init
does a bunch of verification on the attributes, but does not actually allocate anything.
IIRC Calling destroy on a mutex sets the 'kind' of the mutex to an invalid value so that attempting to use it again fails. Before it does that it also attempts to see if the mutex is currently in use elsewhere, and will return EBUSY
if it is. I do not have the nptl source code on here to verify but I think that is about it.
Upvotes: 1
Reputation: 6183
I think with statically allocated mutexes, threads of the same program can only share it until their scope ends,
A static allocation is an allocation that is made when the program starts up and is released when the program shuts down, so it will not just end with the scope.
but with dynamically allocated mutexes, threads of different program would be able to interact with the mutex.
What do you mean by different programs? If you mean inter-process communication, then no.
Take a look at this SO answer, its all a bit more complicated as it seems.
If possible, i suggest you to use the boost library, or if your compiler supports it, std::thread
C++11 extentension(when programing c++).
Upvotes: 1