进程间通信之信号量--使用信号实现生产者消费者问题
生产者消费者是数学中的一个经典的问题,也是编程中的一个经典问题。
本示例采用信号量来解决这个问题,其实,最终也就是进程之间同步的问题。
生产者源代码如下:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/stat.h> #include <sys/sem.h> int sem_id; void init() { key_t key; int ret; unsigned short sem_array[2]; //0代表生产者,1代表消费者 union semun { int val; struct semid_ds *buf; unsigned short *array; }arg; key=ftok(".",'s'); sem_id=semget(key,2,0777|IPC_CREAT); sem_array[0]=0; sem_array[1]=100; arg.array=sem_array; ret=semctl(sem_id,0,SETALL,arg); if(ret==-1) { perror("semctl"); exit(1); } printf("productor init is %d\n",semctl(sem_id,0,GETVAL)); printf("consumer init is %d\n",semctl(sem_id,1,GETVAL)); } void del() { semctl(sem_id,IPC_RMID,0); } int main() { struct sembuf sops[2]; int retv; sops[0].sem_num= 0; sops[0].sem_op = 1; sops[0].sem_flg = 0; sops[1].sem_num= 1; sops[1].sem_op = -1; sops[1].sem_flg = 0; init(); printf("this is productor\n"); while(1) { printf("\n\nbefore produce\n"); printf("productor number is %d\n",semctl(sem_id,0,GETVAL)); printf("space number is %d\n",semctl(sem_id,1,GETVAL)); retv=semop(sem_id,&sops[1],1); //if(retv==-1) printf("no work semo on sops[0] retv%d\n",retv); printf("now producting....\n"); retv=semop(sem_id,&sops[0],1); //if(retv==-1) printf("no work semo on sops[0] retv=%d\n",retv); printf("\nafter produce\n"); printf("productor number is %d\n",semctl(sem_id,0,GETVAL)); printf("space number is %d\n",semctl(sem_id,1,GETVAL)); sleep(1); } del(); return 0; }
消费者源代码如下:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/stat.h> #include <sys/sem.h> int sem_id; void init() { key_t key; key=ftok(".",'s'); sem_id=semget(key,2,0777|IPC_CREAT); } int main() { struct sembuf sops[2]; sops[0].sem_num= 0; sops[0].sem_op = -1; sops[0].sem_flg = 0; sops[1].sem_num= 1; sops[1].sem_op = 1; sops[1].sem_flg = 0; init(); printf("this is customer\n"); while(1) { printf("\n\nbefore consumer\n"); printf("productor number is %d\n",semctl(sem_id,0,GETVAL)); printf("space number is %d\n",semctl(sem_id,1,GETVAL)); semop(sem_id,&sops[0],1); printf("now consuming....\n"); semop(sem_id,&sops[1],1); printf("\nafter consume\n"); printf("productor number is %d\n",semctl(sem_id,0,GETVAL)); printf("space number is %d\n",semctl(sem_id,1,GETVAL)); sleep(3); } return 0; }