Interprocess mutex with pthreads

13,322

Solution 1

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.

Solution 2

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;
}
Share:
13,322
MetallicPriest
Author by

MetallicPriest

Updated on June 04, 2022

Comments

  • MetallicPriest
    MetallicPriest almost 2 years

    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.

  • cnicutar
    cnicutar almost 13 years
    @MetallicPriest Enough for what ? Put more effort into your questions
  • MetallicPriest
    MetallicPriest almost 13 years
    I mean, would the variable of type sem_t require some special initialization to make it work for inter process communication.
  • cnicutar
    cnicutar almost 13 years
    Did you actually read my answer ? "Use sem_init for unnamed semaphores or sem_open for named ones".
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE almost 13 years
    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.
  • cnicutar
    cnicutar almost 13 years
    @R.. I actually didn't know pthread mutexes can be shared across processes :-) Of course, you're absolutely right.
  • Vincenzo Pii
    Vincenzo Pii about 11 years
    -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.
  • kuga
    kuga over 7 years
    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.
  • cnicutar
    cnicutar over 7 years
    @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?
  • kuga
    kuga over 7 years
    Actually its a litte bit more complicated ;) see: pubs.opengroup.org/onlinepubs/009695399/functions/…. You should probably activate the PTHREAD_MUTEX_ERRORCHECK setting.
  • Jeff Hammond
    Jeff Hammond over 4 years
    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.
  • Changbin Du
    Changbin Du about 4 years
    because it is wrong! The mutex must be placed at shared memory(anoymous or file mapped) but not a global var.
  • Jeff Hammond
    Jeff Hammond about 4 years
    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?
  • Changbin Du
    Changbin Du about 4 years
    This even is not a good demo. Declaring shm_mutex as a simple global var won't work. This can confuse readers.
  • Jeff Hammond
    Jeff Hammond about 4 years
    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.
  • Changbin Du
    Changbin Du about 4 years
    I'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.
  • M.M
    M.M almost 4 years
    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"
  • Jeff Hammond
    Jeff Hammond about 2 years
    @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
    Jeff Hammond about 2 years
    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.
  • M.M
    M.M about 2 years
    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
  • Jeff Hammond
    Jeff Hammond about 2 years
    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.