User Tools

Site Tools


notes:sharing_pthreads_primitives_between_processes

This is an old revision of the document!


Sharing pthreads primitives between processes

This code example shows a pthreads mutex and condition variable being placed in shared memory and set to be shared across a fork() call:

share_pthreads_fork_example.c
/* Example code for PTHREAD_PROCESS_SHARED used with condition variables and
 * mutexes. Note that most error handling has been ommitted for brevity - of
 * course in production code, the result of all the pthreads functions should
 * should be checked for errors.
 */
 
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
 
 
void logmsg(const char *msg)
{
  static time_t start_time = 0;
  if (start_time == 0) {
    start_time = time(NULL);
  }
  printf("[%lld] %s\n", (long long)(time(NULL) - start_time), msg);
}
 
 
int parent_process(pthread_mutex_t *mutex, pthread_cond_t *cond)
{
  logmsg("PARENT: sleeping for 1 second.");
  sleep(1);
  logmsg("PARENT: acquiring mutex");
  pthread_mutex_lock(mutex);
  logmsg("PARENT: waking child.");
  pthread_cond_signal(cond);
  pthread_mutex_unlock(mutex);
  logmsg("PARENT: waiting for child.");
  wait(NULL);
  logmsg("PARENT: terminating.");
  return 0;
}
 
 
int child_process(pthread_mutex_t *mutex, pthread_cond_t *cond)
{
  logmsg("CHILD: acquiring mutex.");
  pthread_mutex_lock(mutex);
  logmsg("CHILD: sleeping for 2 seconds.");
  sleep(2);
  logmsg("CHILD: waiting to be woken.");
  pthread_cond_wait(cond, mutex);
  pthread_mutex_unlock(mutex);
  logmsg("CHILD: woken by parent.");
  logmsg("CHILD: sleeping for 1 second.");
  sleep(1);
  logmsg("CHILD: terminating.");
  return 0;
}
 
 
int main()
{
  pid_t ret;
  pthread_cond_t *cond;
  pthread_condattr_t condattr;
  pthread_mutex_t *mutex;
  pthread_mutexattr_t mutexattr;
  int shmid;
  char *shared_block;
 
  /* Create and attach shared memory segment and place mutex and condition
   * variable within it */
  shmid = shmget(IPC_PRIVATE, sizeof(pthread_cond_t) + sizeof(pthread_mutex_t),
                 S_IRWXU);
  shared_block = (char *)shmat(shmid, NULL, 0);
  cond = (pthread_cond_t *)shared_block;
  mutex = (pthread_mutex_t *)(shared_block + sizeof(pthread_cond_t));
 
  /* Set up condition variable attributes */
  pthread_condattr_init(&condattr);
  pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED);
  pthread_cond_init(cond, &condattr);
  pthread_condattr_destroy(&condattr);
 
  /* Set up mutex variable attributes */
  pthread_mutexattr_init(&mutexattr);
  pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED);
  pthread_mutex_init(mutex, &mutexattr);
  pthread_mutexattr_destroy(&mutexattr);
 
  printf("... About to fork.\n");
  ret = fork();
  if (ret < 0) {
    printf("... Failed to fork: %s\n", strerror(errno));
    return 1;
  } else if (ret == 0) {
    return child_process(mutex, cond);
  } else {
    return parent_process(mutex, cond);
  }
}
notes/sharing_pthreads_primitives_between_processes.1359636238.txt.gz · Last modified: 2013/01/31 12:43 by andy