Reputation: 41
I am trying to understand how to do a wait for zero operation in unix. I have this code, but it stops waiting always with the same value as given.
int main(void){
int sem;
struct sembuf sops[2];
if((sem = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600))==-1){
perror("Error semget");
return 100;
}
fork();
//printf("Empieza la accion\n");
if(semctl(sem,0,SETVAL,2)==-1){
printf("Error semctl\n");
exit(100);
}
printf("Value: %d\n",semctl(sem,0,GETVAL));
sops[0].sem_num=0;
sops[0].sem_op=-1;
sops[0].sem_flg=0;
//WAIT(0)
sops[1].sem_num=0;
sops[1].sem_op=0;
sops[1].sem_flg=0;
printf("Value: %d\n",semctl(sem,0,GETVAL));
if(semop(sem,&sops,2)<0) printf("Error semop\n");
printf("Value: %d\n",semctl(sem,0,GETVAL));
printf("End\n");
}
Upvotes: 3
Views: 2502
Reputation: 180351
Gcc complains to me about your code:
sem.c:37: warning: passing argument 2 of ‘semop’ from incompatible pointer type /usr/include/sys/sem.h:59: note: expected ‘struct sembuf *’ but argument is of type ‘struct sembuf (*)[2]’
This is the code it doesn't like:
if(semop(sem,&sops,2)<0) printf("Error semop\n");
If I change it to
if(semop(sem,sops,2)<0) printf("Error semop\n");
then GCC does not complain, and the program hangs indefinitely on the semop()
call, as I would expect.
In particular, note that semop()
applies all the specified operations as an atomic group, or not at all. Your program could only proceed past the semop()
call if the operations specified by the two processes were overlapped, such that the two decrements were performed first, then the two wait-for-zeroes.
Your program works about as you may have expected if I move the SETVAL
operation before the fork()
call, and have each process perform two separate semop()
calls, one to decrement the semaphore, and then one to wait for it to become zero.
Upvotes: 1