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.
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
Interprocess mutex with pthreads
Use a POSIX semaphore initialized to (See below) Use 1
instead.sem_init
for unnamed semaphores or sem_open
for named ones.
sem_t sem;
/* initialize using sem_init or sem_open */
sem_wait(&sem);
/* critical region */
sem_post(&sem);
Many years after initially posting this answer, it has to be updated.
Mutexes should actually be used instead of semaphores. R and kuga's comments (copied verbatim below) explain why. In particular I find kuga's mention that mutexes can only be post
ed by their locking thread most compelling.
R
sem_init requires a nonzero pshared argument to be shared, just like a
mutex would require the pshared attribute. There's no reason to prefer
semaphores over mutexes for this, and in fact mutexes would be better
because you could use a robust mutex which allows you to handle the
(very real!) case where one process dies while holding the lock.
kuga
Additionally to R..`s post, a mutex can only be posted by the thread
that locks it. This is often required and a semaphore does not provide
this feature. So this is not the correct answer, Jeff´s answer should
be flagged as the correct answer.
Is it safe to share synchronization primitives between processes via shared memory?
The answer turns out to be yes. POSIX doesn't require it to be safe to use mutexes through shared memory, but it works on Linux. To be safe, one has to set the PTHREAD_PROCESS_SHARED
attribute through the pthread_mutexattr_setpshared function when creating a lock or condition variable. This explicitly indicates you want any thread to be able to work on the lock, even through shared memory.
Related Topics
Reset Bash History Search Position
Vagrant, Shared Folder: Take Advantage of Inotify Over Nfs
Raw Socket Access as Normal User on Linux 2.4
Gnome Shell Extension Key Binding
How to Find The Version of a Compiled Kernel Module
Snort Message - Warning: No Preprocessors Configured for Policy 0
On Linux, Is Access() Faster Than Stat()
How to Use Vi to Edit a Command in Terminal on Linux
How to Select a Static Port Number for a Custom App
Capture Output of a Bash Command, Parse It and Store into Different Bash Variables
Find Syslog Max Message Length
How to 'Chmod -R +W' with Ant, Files and Folders
Echo - Syntax Error: Bad Substitution
Bash "&" Without Printing "[1]+ Done "
Authenticating Gtk App to Run with Root Permissions
Sed Command Works on Linux, But Not on Os X