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);
}