I am trying out the following piece of code to implement a simple semaphore.

Steps

1. Create Semaphore
2. Initialize it to 1
3. Enter Critical section - SEMAPHORE P Operation
4. >>>> print some numbers >>>>
5. Leave Critical section - SEMAPHORE V Operation
6. Delete Semaphore

Running the program

Execute the program in one terminal.
In another terminal, execute the same program while it is running in terminal 1.

I expect the program in terminal 2 to WAIT for the program in terminal 1 to leave its critical section before it starts running. But this does not happen. Both the programs run simultaneously.

Maybe, my understanding of semaphores is wrong. Could you please point the error in my program?

Thanks.


Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

#define KEY 12

union semun 
{
    int val;
    struct semid_ds *buf;
    unsigned short *array;
};

int main()
{
  int sem_id;
  int i;
 
  printf("PID = **%d**\n",getpid());

  // CREATE SEMAPHORE
  sem_id = semget((key_t)KEY, 1, IPC_CREAT); 

  printf("Semaphore id = %d\n",sem_id);

  // INITIALIZE SEMAPHORE to 1
  union semun cmd1;
  cmd1.val = 1; //any value.
  if(semctl(sem_id, 0, SETVAL, cmd1) == 0) 
    printf("Semaphore SETVAL to %d SUCCESSFUL.\n",cmd1.val);
  else
    {
      printf("Semaphore SETVAL FAILED\n");
      exit(EXIT_FAILURE);
    }


  struct sembuf sem_p = {0,-1,SEM_UNDO};

  // SEMAPHORE P Operation
  if(semop(sem_id, &sem_p, 1) == -1)
  {
    printf("Semaphore P operation FAILED.\n");
    exit(EXIT_FAILURE);
  }
  else
  {
    printf("Process %d >>>>entering critical section>>>>\n",getpid());
  }

  for(i=0;i<10;i++)
    {
      printf("%d\n",i);
      sleep(1);
    }

  struct sembuf sem_v = {0,1, SEM_UNDO};

  // SEMAPHORE V Operation
  if(semop(sem_id, &sem_v, 1) == -1)
  {
    printf("Semaphore V operation FAILED.\n");  
    exit(EXIT_FAILURE);
  }
  else
  {
    printf("Process %d <<<<leaving critical section<<<<\n",getpid());
  }

  // DELETE SEMAPHORE
  union semun cmd2;
  if(semctl(sem_id, 0, IPC_RMID,cmd2) == 0)
    printf("Process %d deleted semaphore %d.\n",getpid(),sem_id);
  else
    printf("Process %d failed to delete semaphore %d.\n",getpid(),sem_id);
 
  exit(EXIT_SUCCESS);
}