开发者

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 1 instead. (See below) Use 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 posted 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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜