I am having trouble using shared memory, semaphores and forks in Unix C. My semaphores are not posix. I create a pointer to shared memory 2*sizeof(float). I initialize the value of my semaphore to 2 with semctl. I do a fork() in a for loop (i<2). In the child processes (if fork() == 0) each child does a p operation on the semaphore (-1), writes to shared memory then does a v operation (+1) then exits. The Parent process does a p operation (-2) on the semaphore, reads the entirety of the shared memory segment(with a for loop) and does a v operation (+2). He waits on the child processes before exiting to avoid zombies. The problem i have in output is that i get :
Parent reading 0
Parent reading 1
Parent reading 0
Parent reading 1
Child writing 0
Child writing 1
When what i should be getting is :
Child writing 0
Child writing 1
Parent reading 0
Parent reading 1
I have tried initializing my semaphore to 1 instead of 2 but that just stalls the program since the semaphore will never have a value of two and thus the parent process will never read.
If what i have understood about semaphores is correct, the fact that i initialize it to 2 means that the parent process can directly read even though none of the children have written anything. How can i resolve this problem?
EDIT: I added a simplified version of my code after request, i have removed error checking, and waiting for children to reduce length.
/** OPEN MEMORY **/
int shmid1 = shmget(1990, (size), IPC_CREAT | 0666 );
float * shmPt = (float*)shmat(shmid1, NULL, 0);
/** CREATE INITIALIZE SEMAPHORE **/
semun1.val = 2;
int semid = semget(1991, 1, 0666 | IPC_CREAT)
semctl(semid, 0, SETVAL, semun1 )
/** CREATE PROCESSES **/
for ( ii = 0; ii < 2; ++ii) {
if ((p = fork()) == 0) {
int semid = semget(1991, 1, 0666);
struct sembuf p_buf;
p_buf.sem_num = 0;p_buf.sem_op = -1;p_buf.sem_flg = SEM_UNDO;
/** LOCK **/
semop(semid, &p_buf,1);
/** WRITE **/
shmPt[ii] = RandomFloat;
v_buf.sem_num = 0;v_buf.sem_op = 1;v_buf.sem_flg = SEM_UNDO;
/** UNLOCK **/
semop(semid, &v_buf,1)
exit(0);
}
else {
int semid = semget(1991, 1, 0666);
struct sembuf p_buf;
p_buf.sem_num = 0;p_buf.sem_op = -2;p_buf.sem_flg = SEM_UNDO;
/** LOCK **/
semop(semid, &p_buf,1);
/** READ **/
for(int j =0;j<2;j++) tabFloat[j] = shmPt[j];
v_buf.sem_num = 0;v_buf.sem_op = 2;v_buf.sem_flg = SEM_UNDO;
/** UNLOCK **/
semop(semid, &v_buf,1)
}
}
EDIT : My ultimate goal is to have 24 children writing one by one into a shared memory segment of the same size and only when it is full, then the parent can read everything and process the information. On top of that all of this needs to be in a while loop (imagine 24 cars that keep generating random times everytime they complete a lap until the first car has finished 50 laps)