Reputation: 30835
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.
Upvotes: 5
Views: 16869
Reputation: 11
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
Upvotes: 1
Reputation: 182754
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.
Upvotes: 8
Reputation: 5652
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;
}
Upvotes: 15