title: Share condition variable & mutex between processes: does mutex have to locked before?
body: <p>I need to some little help to understand how to use condition variables in C to resolve an exercise. Here is a little example:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;pthread.h&gt;
  #include &lt;string.h&gt;
  #include &lt;errno.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;sys/mman.h&gt;
  #include &lt;sys/stat.h&gt;
  #include &lt;fcntl.h&gt;
  
  #define OKTOWRITE "/oktowrite"
  #define MESSAGE "/message"
  #define MUTEX "/lock"
  
  int main(int argc, char** argv)
  {
    pthread_cond_t* condition;
    pthread_mutex_t *mutex;
    char* message;
    int des_cond, des_msg, des_mutex;
    int mode = S_IRWXU | S_IRWXG;
  
    des_mutex = shm_open(MUTEX, O_CREAT | O_RDWR | O_TRUNC, mode);
  
    if (des_mutex &lt; 0)
    {
      perror("failure on shm_open on des_mutex");
      exit(1);
    }
  
    if (ftruncate(des_mutex, sizeof(pthread_mutex_t)) == -1)
    {
      perror("Error on ftruncate to sizeof pthread_cond_t\n");
      exit(-1);
    }
  
    mutex = (pthread_mutex_t*) mmap(NULL, sizeof(pthread_mutex_t),
        PROT_READ | PROT_WRITE, MAP_SHARED, des_mutex, 0);
  
    if (mutex == MAP_FAILED )
    {
      perror("Error on mmap on mutex\n");
      exit(1);
    }
  
    pthread_mutex_init(mutex, NULL );
  
    des_cond = shm_open(OKTOWRITE, O_CREAT | O_RDWR | O_TRUNC, mode);
  
    if (des_cond &lt; 0)
    {
      perror("failure on shm_open on des_cond");
      exit(1);
    }
  
    if (ftruncate(des_cond, sizeof(pthread_cond_t)) == -1)
    {
      perror("Error on ftruncate to sizeof pthread_cond_t\n");
      exit(-1);
    }
  
    condition = (pthread_cond_t*) mmap(NULL, sizeof(pthread_cond_t),
        PROT_READ | PROT_WRITE, MAP_SHARED, des_cond, 0);
  
    if (condition == MAP_FAILED )
    {
      perror("Error on mmap on condition\n");
      exit(1);
    }
  
    pthread_cond_init(condition, NULL );
  
    if (!fork())
    {
      sleep(3);
      pthread_mutex_lock(mutex);
      pthread_cond_signal(condition);
      pthread_mutex_unlock(mutex);
      printf("son signaled\n");
      exit(0);
    }
    else
    {
      printf("wait on condition\n");
  
      pthread_mutex_lock(mutex);
      pthread_cond_wait(condition, mutex);
      pthread_mutex_unlock(mutex);
  
      printf("Signaled by son process, wake up\n");
  
      pthread_mutex_destroy(mutex);
      pthread_cond_destroy(condition);
  
      shm_unlink(OKTOWRITE);
      shm_unlink(MESSAGE);
      shm_unlink(MUTEX);
  
      return 0;
    }
  }
  </code></pre>
  
  <p>The problem is that the father of the process keeps on being locked, even after son's signaling. Everything is in shared memory (using <code>shm_open</code> and <code>mmap</code>) so the condition should be the same for both the processes. 
  Am I maybe making a mistake by locking the mutex before calling wait or signal?</p>
  
  <p>EDIT:
  Thanks to all who helped me.  Here's the right code with the CRITICAL parts marked:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;pthread.h&gt;
  #include &lt;string.h&gt;
  #include &lt;errno.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;sys/mman.h&gt;
  #include &lt;sys/stat.h&gt;
  #include &lt;fcntl.h&gt;
  
  #define OKTOWRITE "/condwrite"
  #define MESSAGE "/msg"
  #define MUTEX "/mutex_lock"
  
  int main(int argc, char** argv) {
  
  pthread_cond_t* condition;
  pthread_mutex_t* mutex;
  char* message;
  int des_cond, des_msg, des_mutex;
  int mode = S_IRWXU | S_IRWXG;
  
  des_mutex = shm_open(MUTEX, O_CREAT | O_RDWR | O_TRUNC, mode);
  
  if (des_mutex &lt; 0) {
      perror("failure on shm_open on des_mutex");
      exit(1);
  }
  
  if (ftruncate(des_mutex, sizeof(pthread_mutex_t)) == -1) {
      perror("Error on ftruncate to sizeof pthread_cond_t\n");
      exit(-1);
  }
  
  mutex = (pthread_mutex_t*) mmap(NULL, sizeof(pthread_mutex_t),
          PROT_READ | PROT_WRITE, MAP_SHARED, des_mutex, 0);
  
  if (mutex == MAP_FAILED ) {
      perror("Error on mmap on mutex\n");
      exit(1);
  }
  
  des_cond = shm_open(OKTOWRITE, O_CREAT | O_RDWR | O_TRUNC, mode);
  
  if (des_cond &lt; 0) {
      perror("failure on shm_open on des_cond");
      exit(1);
  }
  
  if (ftruncate(des_cond, sizeof(pthread_cond_t)) == -1) {
      perror("Error on ftruncate to sizeof pthread_cond_t\n");
      exit(-1);
  }
  
  condition = (pthread_cond_t*) mmap(NULL, sizeof(pthread_cond_t),
          PROT_READ | PROT_WRITE, MAP_SHARED, des_cond, 0);
  
  if (condition == MAP_FAILED ) {
      perror("Error on mmap on condition\n");
      exit(1);
  }
  
  
           /* HERE WE GO */
  /**************************************/
  
      /* set mutex shared between processes */
  pthread_mutexattr_t mutexAttr;
  pthread_mutexattr_setpshared(&amp;mutexAttr, PTHREAD_PROCESS_SHARED);
  pthread_mutex_init(mutex, &amp;mutexAttr);
  
  /* set condition shared between processes */
  pthread_condattr_t condAttr;
  pthread_condattr_setpshared(&amp;condAttr, PTHREAD_PROCESS_SHARED);
  pthread_cond_init(condition, &amp;condAttr);
  
      /*************************************/
  
  if (!fork()) {
  
      sleep(10);
  
      pthread_mutex_lock(mutex);
      pthread_cond_signal(condition);
      printf("son signaled\n");
      pthread_mutex_unlock(mutex);
      exit(0);
  }
  
  else {
  
      printf("father waits on condition\n");
  
       pthread_mutex_lock(mutex);
       pthread_cond_wait(condition, mutex);
       pthread_mutex_unlock(mutex);
  
       printf("Signaled by son process, wake up!!!!!!!!\n");
  
      pthread_condattr_destroy(&amp;condAttr);
      pthread_mutexattr_destroy(&amp;mutexAttr);
      pthread_mutex_destroy(mutex);
      pthread_cond_destroy(condition);
  
      shm_unlink(OKTOWRITE);
      shm_unlink(MESSAGE);
      shm_unlink(MUTEX);
  
  }
  
  return 0;
  
  }
  </code></pre>