#ifndef _JAMES_C_SEMAPHORE_H #define _JAMES_C_SEMAPHORE_H #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> union semun { int val; /* value for SETVAL */ struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ unsigned short *array; /* array for GETALL SETALL */ struct seminfo __buf; /* buffer for IPC_INFO (Linux-specific) */ }; int set_semvalue(int sem_id); void del_semvalue(int sem_id); int semaphore_p(int sem_id); int semaphore_v(int sem_id); #endif #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include "mysem.h" int set_semvalue(int sem_id) { union semun sem_union; sem_union.val = 1; if (semctl(sem_id, 0, SETVAL, sem_union) == -1) return -1; return 0; } void del_semvalue(int sem_id) { union semun sem_union; if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1) perror("Failed to delete semaphore"); } int semaphore_p(int sem_id) { struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = -1; /* *P() */ sem_b.sem_flg = SEM_UNDO; if (semop(sem_id, &sem_b, 1) == -1) { fprintf(stderr, "semaphore_p failed\n"); return -1; } return 0; } int semaphore_v(int sem_id) { struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = 1; sem_b.sem_flg = SEM_UNDO; if (semop(sem_id, &sem_b, 1) == -1) { fprintf(stderr, "semaphore_v failed\n"); return -1; } return 0; } #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include "mysem.h" int main(int argc, char *argv[]) { int sem_id; int i; int pause_time; char op_char; srand( (unsigned int)getpid() ); op_char = 'a' + rand()%26; /* other process */ sem_id = semget( (key_t)1234, 1, 0666 | IPC_CREAT); if (argc > 1) { if ( set_semvalue(sem_id) < 0) { fprintf(stderr, "Failed to initialize semaphore\n"); exit(-1); } op_char = 'X'; /* creation process */ sleep(2); } for (i=0; i<5; i++) { if (semaphore_p(sem_id) < 0) exit(-1); printf("%c", op_char); fflush(stdout); pause_time = rand()%3; sleep(pause_time); printf("%c", op_char); fflush(stdout); if (semaphore_v(sem_id) < 0) exit(-1); sleep(pause_time); } printf("\n%d - finished\n", getpid()); if (argc > 1) { sleep(10); del_semvalue(sem_id); } return 0; }