title: Using semaphores to avoid race-condition
body: <p>I had to create a race condition program using processes and so did I. Now, I am trying to solve it using semaphores. I've got two critical sections and I am trying to secure them using the semaphore I create in <code>initStem()</code> using <code>semctl()</code>.
  <code>P()</code> and <code>V()</code> increment and decrement the mutex of the semaphore specified in their second parameter.</p>
  
  <p>Unfortunately, it seems that my race condition is still there : My output is : </p>
  
  <pre><code>value in parent: 4
  value after child exec: 4
  </code></pre>
  
  <p>When it should be :</p>
  
  <pre><code>value in parent: 4
  value after child exec: 5
  </code></pre>
  
  <p>(5 + 1 - 1 = 5...)</p>
  
  <p>Here is my code :</p>
  
  <pre><code>#define KEY 4567
  #define PERMS 0660
  #define ID_PROJ "race"
  #define NB_SEMAPHORES 1
  
  int initSem(char **argv);
  int P(int semid, int semnum);
  int V(int semid, int semnum);
  
  int main(int argc, char **argv) {
  
      int id, pid1;
      int *shared;
      int tmp;
  
  if ((id = shmget(KEY, 2*sizeof(int), IPC_CREAT | PERMS)) == -1) {
      perror("shmget");
      exit(-1);
  }
  
  shared=(int *)shmat(id, NULL, 0);
  shared[0]=5; // value
  shared[1]=initSem(argv); // semaphore id
  
  if ((pid1=fork()) == 0) {
      P(shared[1], 0); // Start critical section
      tmp=shared[0];
      tmp++;
      sleep(2);
      shared[0]=tmp;
      V(shared[1], 0); // End critical section
      exit(0);
  }
  else {
      P(shared[1], 0); // Start
      tmp=shared[0];
      tmp--;
      sleep(4);
      shared[0]=tmp;
      V(shared[1], 0); // End
  
      printf("value in parent: %d\n", shared[0]);
  
      waitpid(pid1, NULL, 0);
      printf("value after child exec: %d\n", shared[0]);
      shmctl(id, IPC_RMID, NULL);
  }
  }
  </code></pre>
  
  <p><strong>So I am wondering</strong> : am I using my semaphore correctly ? Am I doing it right by using the same semaphore in both of my processes ?</p>
  
  <p>Edit :</p>
  
  <p>Here are the 3 functions I am using to interact with my semaphores:</p>
  
  <pre><code>int initSem(char **argv) {
      int i,semid;
      key_t key=ftok(argv[0], 'P');
      semid=semget(key, NB_SEMAPHORES, IPC_CREAT | PERMS);
      for(i=0 ; i&lt;NB_SEMAPHORES ; i++)
              semctl(key, i, SETVAL, 1);
      return semid;
  }
  
  int P(int semid, int semnum) {
      struct sembuf op;
      op.sem_num=semnum;
      op.sem_op=-1;
      op.sem_flg=0;
      semop(semid, &amp;op, 1);
  }
  
  int V(int semid, int semnum) {
      struct sembuf op;
      op.sem_num=semnum;
      op.sem_op=1;
      op.sem_flg=0;
      semop(semid, &amp;op, 1);
  }
  </code></pre>