#include #include #include #include #include union semun { int val ; struct semid_ds *buf ; ushort *array; }; initsem(key_t semkey) { int status = 0, semid; /* * try to create it. * If we do, then initialize it * otherwise just get it */ semid = semget(semkey, 1, 0666|IPC_CREAT|IPC_EXCL); if ( semid == -1 ){ if ( errno == EEXIST ) semid = semget(semkey, 1, 0); } else { union semun arg; arg.val = 1; status = semctl(semid, 0, SETVAL, arg); } if ( semid == -1 || status == -1 ){ perror("initsem"); return -1 ; } return semid; } int waitfor(int semid) { struct sembuf action; action.sem_num = 0; action.sem_op = -1; /* try to decrement */ action.sem_flg = SEM_UNDO ; if ( semop(semid, &action, 1) == -1 ){ perror("semop in waitfor failed"); exit(1); } return 0; } int release(int semid) { struct sembuf action; action.sem_num = 0; action.sem_op = 1; /* try to decrement */ action.sem_flg = SEM_UNDO ; if ( semop(semid, &action, 1) == -1 ){ perror("semop in waitfor failed"); exit(1); } return 0; } main() { key_t semkey = 5566; int i; for(i = 0 ; i<3 ; i++ ) { if ( fork() == 0 ) handlesem(semkey); } } handlesem(key_t skey) { int semid; int pid = getpid(); semid = initsem(skey); if ( semid < 0 ){ exit(1); } printf("\nPID %d before critical section\n", pid); waitfor(semid); printf("PID %d in critical section\n", pid); sleep(10); printf("PID %d leaving critical section\n", pid); release(semid); printf("PID %d done\n", pid); exit(0); }