linux c 多线程编程练习(三)

再来一道经典题目

题目大意如下:有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个有多个缓冲区的缓冲池,生产者将它生产的产品放入一个缓冲区中,消费者可以从缓冲区中取走产品进行消费,所有生产者和消费者都是异步方式运行的,但它们必须保持同步,即不允许消费者到一个空的缓冲区中取产品,也不允许生产者向一个已经装满产品且尚未被取走的缓冲区中投放产品。


模拟一个拥有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;
}











  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值