If semget call shares the semaphore between parent and child process? I have this code and for the same code I observed that if parent runs first, child sometimes get the changed semaphore value but when child process runs first, parent never seems to carry on the changed semaphore. Why is this happening? Can anyone please explain this thing to me?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <math.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
int main() {
int semid = semget(12, 2, 0666|IPC_CREAT);
int status;
semctl(semid, 0, SETVAL, 12);
semctl(semid, 1, SETVAL, 1);
short int outarray[2], last;
char output[200];
struct sembuf obj1[] = { {0, -1, SEM_UNDO}, {1, -1, SEM_UNDO} };
struct sembuf obj2[] = { {0, 0, SEM_UNDO}, {1, 0, SEM_UNDO} };
struct sembuf obj3[] = { {0, 1, SEM_UNDO}, {1, 1, SEM_UNDO} };
int pid = fork();
//wait(&status);
semctl(semid, 2, GETALL, outarray);
printf("OUT(%d):%d %d %d\n", getpid(),outarray[0], outarray[1], last);
if(pid!=0) {
printf("Semid Parent:%d\n",semid);
semctl(semid, 2, GETALL, outarray);
printf("%d %d %d\n", outarray[0], outarray[1], last);
printf("Parent Check1\n");
last = semop(semid, obj1, 2);
semctl(semid, 2, GETALL, outarray);
printf("%d %d %d\n", outarray[0], outarray[1], last);
printf("Parent Check2\n");
last = semop(semid, obj2, 2);
semctl(semid, 2, GETALL, outarray);
printf("%d %d %d\n", outarray[0], outarray[1], last);
printf("Parent Check3\n");
//sleep(10);
}
else {
semctl(semid, 2, GETALL, outarray);
printf("Child: %d %d %d\n", outarray[0], outarray[1], last);
//leep(2);
printf("Semid Child:%d\n",semid);
int x;
printf("Child Check1\n");
last = semop(semid, obj1, 2);
semctl(semid, 2, GETALL, outarray);
printf("child %d %d %d\n", outarray[0], outarray[1], last);
//sleep(2);
printf("Child Check2\n");
last = semop(semid, obj3, 2);
semctl(semid, 2, GETALL, outarray);
printf("child %d %d %d\n", outarray[0], outarray[1], last);
//sleep(2);
printf("Child Check3\n");
last = semop(semid, obj1, 2);
semctl(semid, 2, GETALL, outarray);
printf("child %d %d %d\n", outarray[0], outarray[1], last);
//sleep(2);
printf("Child Check4\n");
//sleep(10);
semctl(semid, 2, GETALL, outarray);
printf("child %d %d %d\n", outarray[0], outarray[1], last);
semctl(semid, 2, GETNCNT, x);
printf("%d\n",x);
sleep(5);
}
return 0;
}
And the output:
This is the output when parent runs first
OUT(3167):12 1 0
Semid Parent:0
12 1 0
Parent Check1
11 0 0
Parent Check2
OUT(3168):12 1 0
Child: 11 0 0
Semid Child:0
Child Check1
This is the output when child runs first. I added a wait inside the if loop
OUT(3679):12 1 0
OUT(3680):12 1 0
Child: 12 1 0
Semid Child:0
Child Check1
child 11 0 0
Child Check2
child 12 1 0
Child Check3
child 11 0 0
Child Check4
child 11 0 0
0
Semid Parent:0
12 1 0
Parent Check1
11 0 0
Parent Check2