Interprocess mutex with pthreads
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.
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;
}
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.
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
精彩评论