I want to use a mutex which will be used to synchronize access to some variables residing in the memory shared b/w two different processes. How can I achieve that. Code sample to perform that will be very appreciated.
-
1Why does your title say "pthreads" but you are asking about "processes"? How are you sharing memory between processes anyway, with memory mapping? – Kerrek SB Jun 25 '11 at 11:52
-
I'm sharing memory by allocating it before forking. So one process is the parent and the other is child. By pthread, I meant using pthread_mutex_lock. – MetallicPriest Jun 25 '11 at 12:08
-
2I think `fork` creates _copies_ of the memory, so it's not exactly "shared". – Kerrek SB Jun 25 '11 at 12:11
-
2Kerrek SB, actually i attach shared memory by using shmget and shmat before forking, so they get mapped to the same address in both processes! – MetallicPriest Jun 25 '11 at 12:16
-
1@KerrekSB Operating systems don't care as much as you probably think about the distinction between threads and processes. In Linux, they are all 'clone'd anyways. – Jeff Hammond Feb 12 '15 at 14:15
-
@MetallicPriest You should use POSIX shared memory (shm_open) instead of Sys5 (shmget). – Jeff Hammond Feb 12 '15 at 14:16
3 Answers
The following example demonstrates the creation, use and destruction of a Pthread interprocess mutex. Generalizing the example for multiple processes is left as an exercise for the reader.
#include <pthread.h>
pthread_mutex_t shm_mutex;
int main(void)
{
int err;
pthread_mutexattr_t attr;
err = pthread_mutexattr_init(&attr); if (err) return err;
err = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); if (err) return err;
err = pthread_mutex_init(&shm_mutex, &attr); if (err) return err;
err = pthread_mutexattr_destroy(&attr); if (err) return err;
err = pthread_mutex_lock(&shm_mutex); if (err) return err;
err = pthread_mutex_unlock(&shm_mutex); if (err) return err;
err = pthread_mutex_destroy(&shm_mutex); if (err) return err;
return 0;
}

- 5,374
- 3
- 28
- 45
-
It would be nice to know why folks downvote this answer. I don't show how to create processes because that is a mostly orthogonal issue. It's also context-dependent. I'm an HPC programmer, so I create processes with MPI. Others might want an example using fork() or exec(). I'm less qualified to write those examples. – Jeff Hammond Dec 31 '19 at 17:21
-
because it is wrong! The mutex must be placed at shared memory(anoymous or file mapped) but not a global var. – Changbin Du Feb 24 '20 at 07:36
-
Do you notice that the code is demonstrating the API usage and very explicitly not showing a complete example? Hence the part that is left as an exercise to the reader? – Jeff Hammond Feb 24 '20 at 11:05
-
This even is not a good demo. Declaring shm_mutex as a simple global var won't work. This can confuse readers. – Changbin Du Feb 25 '20 at 12:39
-
You are correct that my code cannot be copy-pasted into a nontrivial application, but it is correct as written, because a global variable is legal when the code runs as a single process, which is explicitly stated in the answer already. If you have something constructive to say, why not answer the question yourself with something that meets your standards. – Jeff Hammond Feb 25 '20 at 19:06
-
3I'm not denying your answer. I am suggesting you should make it clear how the shared mutex can be created. This is one of the key point of this problem. You can even simply add pesudo code. – Changbin Du Mar 21 '20 at 00:03
-
The question is about an interprocess mutex , the answer should show that rather than claiming "this is a single process mutex, you have to figure out yourself how to do an interprocess one" – M.M Jun 04 '20 at 03:00
-
@M.M `pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)` is exactly the creation of an *interprocess mutex*. What is not shown is the separate question of creating multiple processes. The OP did not ask how to create processes, so I did not not answer that. – Jeff Hammond Feb 14 '22 at 12:47
-
I deleted this answer for ~1.5 years because of the pointless hate I got from you two. Please keep hating if you want me to delete it again. – Jeff Hammond Feb 14 '22 at 12:48
-
Recommendations on how to improve the answer aren't "pointless hate". You can always mark the answer as "community wiki" if you don't want to get notifications for comments on it – M.M Feb 14 '22 at 13:02
-
Scroll up and hit the `edit` button. Actually make the world a better place instead of continuously whining at me that I interpret the question differently than you do. – Jeff Hammond Feb 14 '22 at 13:25
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.

- 178,505
- 25
- 365
- 392
-
@MetallicPriest Enough for what ? Put more effort into your questions – cnicutar Jun 25 '11 at 12:34
-
I mean, would the variable of type sem_t require some special initialization to make it work for inter process communication. – MetallicPriest Jun 25 '11 at 12:38
-
1Did you actually read my answer ? "*Use sem_init for unnamed semaphores or sem_open for named ones*". – cnicutar Jun 25 '11 at 12:39
-
1`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. – R.. GitHub STOP HELPING ICE Jun 25 '11 at 13:58
-
@R.. I actually didn't know pthread mutexes can be shared across processes :-) Of course, you're absolutely right. – cnicutar Jun 25 '11 at 17:58
-
2-1 as a justification on why `sem_t` should be preferred over `pthread mutexes` is missing, or, alternatively, a note on the possibility of using `pthread mutexes`. – Vincenzo Pii Apr 03 '13 at 14:53
-
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. – kuga Jan 02 '17 at 12:19
-
@kuga Thanks a lot for that, I didn't know. I edited the answer and included your mention. Can you add a link to some documentation? – cnicutar Jan 03 '17 at 10:16
-
1Actually its a litte bit more complicated ;) see: http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_mutex_lock.html. You should probably activate the PTHREAD_MUTEX_ERRORCHECK setting. – kuga Jan 03 '17 at 15:41
As the reply from Changbin Du in the previous answer,
The mutex must be placed at shared memory(anoymous or file mapped) but not a global var.
Here is the demo:
// The mutex must be placed at shared memory(anoymous or file mapped) but not a global var
pthread_mutex_t *shm_lock;
void child_start()
{
pthread_mutex_lock(shm_lock);
printf("Child process has started\n");
sleep(1);
printf("Child process has finished\n");
pthread_mutex_unlock(shm_lock);
}
void parent_start()
{
pthread_mutex_lock(shm_lock);
printf("Parent process has started\n");
sleep(1);
printf("Parent process has finished\n");
pthread_mutex_unlock(shm_lock);
}
int main(void)
{
// init shared lock at anoymous shared memory
shm_lock = (pthread_mutex_t*) mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(shm_lock, &attr);
pthread_mutexattr_destroy(&attr);
pid_t pid = fork();
if (pid == 0)
{
child_start();
return 0;
}
parent_start();
wait(NULL);
pthread_mutex_destroy(shm_lock);
return 0;
}
Then, the correct log will be printed.
Parent process has started
Parent process has finished
Child process has started
Child process has finished

- 11
- 2