#include #include #include #include #include #include #include #include #define FTOK_PATH "/dev/zero" #define FTOK_PROJID 0x22 union semun { int val; struct semid_ds *buf; unsigned short *arry; }; int semaphore_init(void); int semaphore_p(int semid); int semaphore_v(int semid); void semaphore_term(int semid); int main(int argc, char **argv) { int semid; pid_t pid; int i; if( (semid=semaphore_init()) < 0) { printf("semaphore initial failure: %s\n", strerror(errno)); return -1; } if( (pid=fork()) < 0) { printf("fork() failure: %s\n", strerror(errno)); return -2; } else if( 0 == pid) /* child process */ { printf("Child process start running and do something now...\n"); sleep(3); printf("Child process do something over...\n"); semaphore_v(semid); sleep(1); printf("Child process exit now\n"); exit(0); } printf("Parent process P operator wait child process over\n"); semaphore_p(semid); printf("Parent start do something now...\n"); sleep(2); printf("Child process exit and "); semaphore_term(semid); return 0; } int semaphore_init(void) { key_t key; int semid; union semun sem_union; if( (key=ftok(FTOK_PATH, FTOK_PROJID)) < 0 ) { printf("ftok() get IPC token failure: %s\n", strerror(errno)); return -1; } semid = semget(key, 1, IPC_CREAT|0644); if( semid < 0) { printf("semget() get semid failure: %s\n", strerror(errno)); return -2; } sem_union.val = 0; if( semctl(semid, 0, SETVAL, sem_union)<0 ) { printf("semctl() set initial value failure: %s\n", strerror(errno)); return -3; } printf("Semaphore get key_t[0x%x] and semid[%d]\n", key, semid); return semid; } void semaphore_term(int semid) { union semun sem_union; if( semctl(semid, 0, IPC_RMID, sem_union)<0 ) { printf("semctl() delete semaphore ID failure: %s\n", strerror(errno)); } return ; } int semaphore_p(int semid) { struct sembuf _sembuf; _sembuf.sem_num = 0; _sembuf.sem_op = -1; _sembuf.sem_flg = SEM_UNDO; // IPC_NOWAIT SEM_UNDO if( semop(semid, &_sembuf, 1) < 0 ) { printf("semop P operator failure: %s\n", strerror(errno)); return -1; } return 0; } int semaphore_v(int semid) { struct sembuf _sembuf; _sembuf.sem_num = 0; _sembuf.sem_op = 1; _sembuf.sem_flg = SEM_UNDO; // IPC_NOWAIT SEM_UNDO if( semop(semid, &_sembuf, 1) < 0 ) { printf("semop V operator failure: %s\n", strerror(errno)); return -1; } return 0; }