信号量实现生产者消费者问题
Posted xnqc1314
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了信号量实现生产者消费者问题相关的知识,希望对你有一定的参考价值。
生产消费问题是一个经典的数学问题,要求生产者---消费者在固定的仓库空间条件下,生产者每生产一个
产品将占用一个仓库空间,生产者生产的产品库存不能越过仓库的存储量,消费者每消费一个产品将增加
一个仓库空间,消费者在仓库产品为0时不能再消费。
以下使用了两个信号量,一个用来管理消费者即sem_produce,另一个用来管理生产者即sem_custom,
sem_produce表示当前仓库可用空间的数量,sem_custom用来表示当前仓库中产品的数量。
- 对于生产者来说,其需要申请的资源为仓库中的剩余空间,因此,生产者在生产一个产品前需要申请
sem_produce信号量。当此信号量的值大于0,即有可用空间,将生产产品,并将sem_produce的值减去1
(因为占用了一个空间);同时,当其生产一个产品后,当前仓库的产品数量增加1,需要将sem_custom信号
量自动加1。
- 对于消费者来说,其需要申请的资源为仓库中的产品,因此,消费者在消费一个产品前将申请sem_cu
stom信号量。当此信号量的值大于0时,即有可用产品,将消费一个产品,并将sem_custom信号量的值减
去1(因为消费了一个产品);同时,当消费一个产品,当前仓库的剩余空间增加1,需要将sem_produce信号
量自动加1。
下面是生产者端的代码:
//sem_productor.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/sem.h> #include <errno.h> #include <sys/types.h> #include <sys/ipc.h> int sem_id; void init() { key_t key; int ret; unsigned short sem_array[2]; union semun { int val; struct semid_ds *buf; unsigned short *array; }arg; key= ftok("mysem",‘s‘); sem_id= semget(key,2,IPC_CREAT|0644); sem_array[0]= 0; sem_array[1]= 100; arg.array= sem_array; ret= semctl(sem_id,0,SETALL,arg); if(ret== -1) { printf("SETALL failed (%d) ",errno); } printf("productor init is %d ",semctl(sem_id,0,GETVAL)); printf("space init is %d ",semctl(sem_id,1,GETVAL)); } void del() { semctl(sem_id,0,IPC_RMID); } int main(int argc,char *argv[]) { 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 productor "); while(1) { printf(" before produce: "); printf("productor number is %d ",semctl(sem_id,0,GETVAL)); printf("space number is %d ",semctl(sem_id,1,GETVAL)); semop(sem_id,(struct sembuf*)&sops[1],1); printf("now producing... "); semop(sem_id,(struct sembuf*)&sops[0],1); printf(" after produce "); printf("space number is %d ",semctl(sem_id,1,GETVAL)); printf("productor number is %d ",semctl(sem_id,0,GETVAL)); sleep(2); } del(); return 0; }
下面是消费者端的代码:
//sem_customer.c #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <errno.h> int sem_id; void init() { key_t key; key=ftok("mysem",‘s‘); sem_id= semget(key,2,IPC_CREAT|0644); } int main(int argc,char *argv[]) { 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 "); while(1) { printf(" before consume: "); int ret= semctl(sem_id,0,GETVAL); int ret1= semctl(sem_id,1,GETVAL); printf("productor is %d ",ret); printf("space is %d ",ret1); semop(sem_id,(struct sembuf*)&sops[0],1); printf("now consuming... "); semop(sem_id,(struct sembuf*)&sops[1],1); printf(" after consume "); printf("productor number is %d ",semctl(sem_id,0,GETVAL)); printf("space number is %d ",semctl(sem_id,1,GETVAL)); sleep(3); } return 0; }
以上是关于信号量实现生产者消费者问题的主要内容,如果未能解决你的问题,请参考以下文章
使用信号量实现有限缓冲区的生产者和消费者问题(使用fork(),semget()等函数,能在GCC下运行)