Semaphore (セマフォ) のサンプル
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) /* union semun is defined by including <sys/sem.h> */ #else /* according to X/OPEN we have to define it ourselves */ union semun { int val; /* value for SETVAL */ struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ unsigned short int *array; /* array for GETALL, SETALL */ struct seminfo *__buf; /* buffer for IPC_INFO */ }; #endif static int sem_id; static int semaphore_p(void) { 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(0); } return(1); } static int semaphore_v(void) { struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = 1; /* V() */ sem_b.sem_flg = SEM_UNDO; if (semop(sem_id, &sem_b, 1) == -1) { fprintf(stderr, "semaphore_v failed\n"); return(0); } return(1); } static int set_semvalue(void) { union semun sem_union; sem_union.val = 1; if (semctl(sem_id, 0, SETVAL, sem_union) == -1) return(0); return(1); } int main(int args, char** argv){ key_t key = ftok(argv[1], 1); sem_id = semget(key, 1, 0666 | IPC_CREAT | IPC_EXCL); if(-1 == sem_id){ sem_id = semget(key, 1, 0666 | IPC_CREAT); } else { set_semvalue(); } int retry=5; while(retry--){ if( semaphore_p() ) break; printf("pid %d is waiting\n", getpid()); fflush(stdout); sleep(1); } printf(">>pid %d is in critical section\n", getpid()); fflush(stdout); sleep(10); printf("<<pid %d is in critical section\n", getpid()); fflush(stdout); semaphore_v(); }
# ./semaphore /tmp/a.out & # ./semaphore /tmp/a.out & >>pid 14654 is in critical section <<pid 14654 is in critical section >>pid 14655 is in critical section <<pid 14655 is in critical section
排他処理されているのが確認できる。