再来一道经典题目
题目大意如下:有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个有多个缓冲区的缓冲池,生产者将它生产的产品放入一个缓冲区中,消费者可以从缓冲区中取走产品进行消费,所有生产者和消费者都是异步方式运行的,但它们必须保持同步,即不允许消费者到一个空的缓冲区中取产品,也不允许生产者向一个已经装满产品且尚未被取走的缓冲区中投放产品。
题目大意如下:有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个有多个缓冲区的缓冲池,生产者将它生产的产品放入一个缓冲区中,消费者可以从缓冲区中取走产品进行消费,所有生产者和消费者都是异步方式运行的,但它们必须保持同步,即不允许消费者到一个空的缓冲区中取产品,也不允许生产者向一个已经装满产品且尚未被取走的缓冲区中投放产品。
模拟一个拥有BUF_NUM个缓冲区,每个缓冲区BUF_SIZE大小的缓冲池。使用信号量和互斥量来控制调度。一个生产者,多个消费者。可能一些地方没有做返回值检错。
我觉得这些问题还是蛮费神的。
/*
* =====================================================================================
*
* Filename: producer_consumer.c
*
* Description:
*
* Version: 1.0
* Created: 2012年09月26日 15时11分13秒
* Revision: 生产者和消费者问题。使用buf模拟一个环形缓冲池
* Compiler: GCC
*
* Author: yadon_z
*
* =====================================================================================
*/
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define BUF_SIZE 100 //每个buf的大小
#define BUF_NUM 50 //有多少个buf
#define PRODUCE_MAX 100 //最大生产多少个buf
pthread_mutex_t buf_mutex = PTHREAD_MUTEX_INITIALIZER;
sem_t producer_sem; //有多少个buf可以生产
sem_t consumer_sem; //有多少个buf可以消费
int producer_i = 0; //生产buf数量总计
int consumer_i = 0; //消费buf数量总计
int buf[BUF_NUM]; //代表BUF_NUM个缓冲区,每个缓冲区有BUF_SIZE个数据
/*-----------------------------------------------------------------
Function Name : print_buf()
Descrypthon : 打印缓冲区
------------------------------------------------------------------*/
void print_buf(char *p)
{
int i;
printf("-%s- ",p);
for (i = 0; i < BUF_NUM; i++) {
printf("%d ", buf[i]);
}
printf("\n");
}
/*-----------------------------------------------------------------
Function Name : producer()
Descrypthon : 生产者函数
------------------------------------------------------------------*/
void *producer()
{
int loop_count = PRODUCE_MAX;
int i ;
while (loop_count--) {
sem_wait(&producer_sem); //如果缓冲池满,等待。
for (i = 0; i < BUF_SIZE; i++) { //开始生产
if (++buf[producer_i%BUF_NUM] == BUF_SIZE) {
//print_buf("pa");
producer_i++;
sem_post(&consumer_sem); //一个缓冲区满了,消费信号+1
}
}
}
}
void *consumer()
{
while (1) {
pthread_mutex_lock(&buf_mutex);
if (consumer_i == PRODUCE_MAX) { //计划产量消费完了,解锁,退出
pthread_mutex_unlock(&buf_mutex);
return (void *)0;
}
while (consumer_i == producer_i) { //不进入正在生产的缓冲区,等待。
sem_wait(&consumer_sem);
}
if (--buf[consumer_i%BUF_NUM] == 0) {
consumer_i++;
sem_post(&producer_sem); //消费完了一个缓冲区
}
pthread_mutex_unlock(&buf_mutex);
//sleep(1);
print_buf("ch");
}
}
int main(int argc, const char *argv[])
{
pthread_t tid[4];
int i,err;
sem_init(&producer_sem, 0, BUF_NUM); //开始状态,10个可生产缓冲区
sem_init(&consumer_sem, 0, 0); //初始化,0个可消费缓冲区
if (err=pthread_create(&tid[0], NULL, producer, NULL)) {
printf("pthread create error %d\n",err);
}
for (i = 1; i < 4; i++) {
if (err=pthread_create(&tid[i], NULL, consumer, NULL)) {
printf("pthread create error %d-%d\n", i, err);
}
}
for (i = 0; i < 4; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}