【十一】 进程间通信——[System V IPC对象]信号灯(semaphore)

来源:互联网 发布:查询淘宝关键词排名 编辑:程序博客网 时间:2024/05/01 20:18

【十一】   进程间通信——[System V IPC对象]信号灯(semaphore)

/*reader.c*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>#include <sys/sem.h>#define N 64#define READ0#define WRITE1union 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) */};void init_sem(int semid, int array[], int num){union semun myun;int i;for (i=0; i<num; i++){myun.val = array[i];semctl(semid, i, SETVAL, myun);}return;}void pv(int semid, int num, int op){struct sembuf buf;buf.sem_num = num;buf.sem_op = op;buf.sem_flg = 1;if (semop(semid, &buf, 1) < 0){exit(0);}return;}int main(){key_t key;int shmid, semid, array[]={0, 1};char *shmadd;if ((key = ftok(".", 's')) < 0){perror("fail to ftok");exit(-1);}if ((semid = semget(key, 2, 0666|IPC_CREAT|IPC_EXCL)) < 0){if (EEXIST == errno){semid = semget(key, 2, 0666);}else{perror("fail to semget");exit(-1);}}else   // the first process {init_sem(semid, array, 2);   // init semaphore}if ((shmid = shmget(key, N, 0666|IPC_CREAT)) < 0){perror("fail to shmget");semctl(semid, 0, IPC_RMID);exit(-1);}shmadd = (char *)shmat(shmid, NULL, 0);while ( 1 ){pv(semid, READ, -1);printf("read from shm : %s", shmadd);pv(semid, WRITE, 1);}return 0;}

/*writer.c*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>#include <sys/sem.h>#define N 64#define READ0#define WRITE1union 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) */};void init_sem(int semid, int array[], int num){union semun myun;int i;for (i=0; i<num; i++){myun.val = array[i];semctl(semid, i, SETVAL, myun);}return;}void pv(int semid, int num, int op){struct sembuf buf;buf.sem_num = num;buf.sem_op = op;buf.sem_flg = 1;semop(semid, &buf, 1);return;}int main(){key_t key;int shmid, semid, array[]={0, 1};char *shmadd;if ((key = ftok(".", 's')) < 0){perror("fail to ftok");exit(-1);}if ((semid = semget(key, 2, 0666|IPC_CREAT|IPC_EXCL)) < 0){if (EEXIST == errno){semid = semget(key, 2, 0666);}else{perror("fail to semget");exit(-1);}}else   // the first process {init_sem(semid, array, 2);   // init semaphore}if ((shmid = shmget(key, N, 0666|IPC_CREAT)) < 0){perror("fail to shmget");semctl(semid, 0, IPC_RMID);exit(-1);}shmadd = (char *)shmat(shmid, NULL, 0);while ( 1 ){pv(semid, WRITE, -1);printf("write to shm : ");fgets(shmadd, N, stdin);if (strncmp(shmadd, "quit", 4) == 0) break;pv(semid, READ, 1);}semctl(semid, 0, IPC_RMID);shmctl(shmid, IPC_RMID, NULL);return 0;}