Do Pthread Mutexes Work Across Threads If in Shared Memory

Using pthread mutex shared between processes correctly

Am I right that the pthread_mutex_init doesn't provide any safe approach to initialize the pthread_mutex_t simultaneously from different processes?

Correct. It is up to you to ensure that only one process calls pthread_mutex_init() on the mutex, and that no process tries to operate on the mutex until that call has successfully returned.

For example, with POSIX shm_open() shared memory regions, you can have the processes try to open the region with the O_CREAT and O_EXCL flags, so that exactly one process will succeed in creating it. This process is then responsible for resizing the shared memory region and initialising the mutex with pthread_mutex_init(). The other processes must then wait for some kind of notification from the initialising process before opening the shared memory region - eg you could have the processes block opening a FIFO O_RDONLY, and have the initialising process notify them by opening the FIFO O_WRONLY (which will cause the open to succeed).

Usually, a shared memory segment will not be the only communication channel between the processes. Typically you would bootstrap the communication through a UNIX domain socket and negotiate the setup of the shared memory region over it, probably even passing the shared memory region file descriptor through the socket with a SCM_RIGHTS message. The shared memory region would then be used to accelerate the performance-sensitive IPC.

Does a PTHREAD mutex only avoid simultaneous access to a resource, or it does anything more?

The pthreads mutex lock and unlock functions are among the list of functions in POSIX "...that synchronize thread execution and also synchronize memory with respect to other threads". So yes, they do more than just interlock execution.

Whether or not they need to issue additional instructions to the hardware is of course architecture dependent (noting that almost every modern CPU architecture will at least happily reorder reads with respect to each other unless told otherwise), but in every case those functions must act as "compiler barriers" - that is, they ensure that the compiler won't reorder, coalesce or omit memory accesses in situations where it would otherwise be allowed to.

It is allowed to have multiple threads reading a shared value without mutual exclusion though - all you need to ensure is that both the writing and reading threads executed some synchronising function between the write and the read. For example, an allowable situation is to have many reading threads that defer reading the shared state until they have passed a barrier (pthread_barrier_wait()) and a writing thread that performs all its writes to the shared state before it passes the barrier. Reader-writer locks (pthread_rwlock_*) are also built around this idea.

Share condition variable & mutex between processes: does mutex have to locked before?

To be shareable between processes a mutex needs to be initialised accordingly via a properly initialised attribute: http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_setpshared.html

#include <pthread.h>

...

pthread_mutex_t * pmutex = NULL;
pthread_mutexattr_t attrmutex;

/* Initialise attribute to mutex. */
pthread_mutexattr_init(&attrmutex);
pthread_mutexattr_setpshared(&attrmutex, PTHREAD_PROCESS_SHARED);

/* Allocate memory to pmutex here. */

/* Initialise mutex. */
pthread_mutex_init(pmutex, &attrmutex);

/* Use the mutex. */

/* Clean up. */
pthread_mutex_destroy(pmutex);
pthread_mutexattr_destroy(&attrmutex);

(error checking left out for the sake of this example's readability)

The same applies to a condition variable which should be shared between processes: http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_condattr_setpshared.html

#include <pthread.h>

...

pthread_cond_t * pcond = NULL;
pthread_condattr_t attrcond;

/* Initialise attribute to condition. */
pthread_condattr_init(&attrcond);
pthread_condattr_setpshared(&attrcond, PTHREAD_PROCESS_SHARED);

/* Allocate memory to pcond here. */

/* Initialise condition. */
pthread_cond_init(pcond, &attrcond);

/* Use the condition. */

/* Clean up. */
pthread_cond_destroy(pcond);
pthread_condattr_destroy(&attrcond);

(error checking left out for the sake of this example's readability)


Also see this answer: https://stackoverflow.com/a/2390670/694576

What part of memory does a mutex lock? (pthreads)

a mutex prevents multiple threads from accessing shared memory

The above is an incorrect statement. By itself, a mutex does not do that. It lets you build code that prevents multiple threads from accessing shared memory or other resources concurrently, but it does not lock anything by itself.

You can build a program that uses a mutex to prevent multiple threads from executing specific pieces of code concurrently. If these pieces of code happen to be accessing a shared memory region, and no other code would try accessing that region concurrently without locking the mutex, then the effect would be that of "locking" that region of memory.

Will shared memory across threads get corrupted if only one thread uses mutex?

Transferring material from my comment into an answer.

Note that all global memory in a process (except thread-local storage, and the local variables in functions) is shared between threads. Shared memory is a term for memory shared between processes.

Whether the memory is being accessed by threads or processes, you need to ensure that access is properly managed (e.g. with mutexes) whenever there's more than one thread of execution that could be accessing the same memory at the same time. These days, it is seldom safe to assume you have a single core at work in a machine, so potential concurrent access is the norm.



Related Topics



Leave a reply



Submit