一、问题描述:
生产者消费者问题(Producer-consumer problem),也称有限缓冲问题(Bounded-buffer problem),是一个多线程同步问题的经典案例。该问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。
代码实现:
Productor:
/*
*运用信号量机制完成生产者消费者模型
*此为生产者
*/
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<errno.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("." , '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)\n" , errno) ;
}
printf("productor init is %d\n\n" , semctl(sem_id , 0 , GETVAL)) ; //打印初始结果,产品数
printf("space init is %d\n\n" , semctl(sem_id , 1 , GETVAL)) ; //空间数
}
void del()
{
semctl(sem_id , IPC_RMID , 0) ; //完成操作后删除,在此程序是一个死循环,不会执行此操作
}
int main(int argc , char* argv[])
{
struct sembuf sops[2] ; //操作两个信号量所使用的结构体
sops[0].sem_num = 0 ;
sops[0].sem_op = 1 ; //执行加1操作,每生产一个产品,对产品数加1
sops[0].sem_flg = 0 ;
sops[1].sem_num = 1 ;
sops[1].sem_op = -1 ; //执行减1操作,对空间数减1
sops[1].sem_flg = 0 ;
init() ;
printf("this is a 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)) ;
semop(sem_id , (struct sembuf*)&sops[1] , 1) ;
printf("now producing.......\n") ;
semop(sem_id , (struct sembuf*)&sops[0] , 1) ;
printf("\nafter produce\n") ;
printf("space number is %d\n\n" , semctl(sem_id , 1 , GETVAL)) ;
printf("product number is %d\n\n" , semctl(sem_id , 0 , GETVAL)) ;
sleep(4) ;
}
del() ;
return 0 ;
}
Customer:
/*
*运用信号量机制完成生产者消费者模型
*此为消费者
*/
#include<stdio.h>
#include<unistd.h>
#include<stdlib.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("." , 's') ;
sem_id = semget(key , 2 , IPC_CREAT | 0644) ; //产生信号量集合
}
int main(int argc , char* argv[])
{
init() ;
struct sembuf sops[2] ; //操作两个信号量所使用的结构体
sops[0].sem_num = 0 ;
sops[0].sem_op = -1 ; //执行减1操作,每消费一个产品,对产品数减1
sops[0].sem_flg = 0 ;
sops[1].sem_num = 1 ;
sops[1].sem_op = 1 ; //执行加1操作,对空间数加1
sops[1].sem_flg = 0 ;
init() ;
printf("this is a customer \n") ;
while(1)
{
printf("\n\nbefore consume:\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 , (struct sembuf*)&sops[1] , 1) ;
printf("now consuming.......\n") ;
semop(sem_id , (struct sembuf*)&sops[0] , 1) ;
printf("\nafter consume\n") ;
printf("space number is %d\n\n" , semctl(sem_id , 1 , GETVAL)) ;
printf("product number is %d\n\n" , semctl(sem_id , 0 , GETVAL)) ;
sleep(4) ;
}
return 0 ;
}
查看结果:
Produtor:
Customer: