码迷,mamicode.com
首页 > 其他好文 > 详细

生产者消费者问题

时间:2015-07-13 20:04:22      阅读:95      评论:0      收藏:0      [点我收藏+]

标签:

生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例。该问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据

一种实现如下:

技术分享
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>

#define MAX 5 //缓冲区的的大小
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

typedef struct{
    char buffer[MAX];
    int count;
}Buffer;

Buffer share = {"", 0};
char ch = A;

void *producer(void *arg)
{
    printf("Producer : starting \n");
    while(ch != K)
    {
        pthread_mutex_lock(&mutex);
        if(share.count != MAX)
        {
             share.buffer[share.count++] = ch++;
             printf("Producer: put char[%c]\n", ch-1);
             if(share.count == MAX)
             {
                 printf("Producer: signaling full\n");
                 pthread_cond_signal(&cond);//若果缓存满了发送信号
             }
        }
        pthread_mutex_unlock(&mutex);
    }
    sleep(1);
    printf("Produce: Exiting \n");
    pthread_exit(NULL);
}

void *consumer(void *junk)
{
    int i;
    printf("Consumer : starting\n");
    while (ch != K)
    {
        pthread_mutex_lock(&mutex);
        printf("\t Consumer : Waiting\n");
        while(share.count != MAX){
            pthread_cond_wait(&cond, &mutex);  //条件不成立释放锁.
            printf("Consumer wating for FULL signal\n");
        }
        printf("Consumer : getting buffer :: ");
        for(i = 0; share.buffer[i] && share.count;++i, share.count--)
            putchar(share.buffer[i]);
        putchar(\n);
        pthread_mutex_unlock(&mutex);
    }
}

int main()
{
    pthread_t read, write;
    pthread_create(&read, NULL, (void *) consumer, NULL);
    pthread_create(&write, NULL, (void *)producer, NULL);

    pthread_join(read, NULL);
    pthread_join(write, NULL);
    return 0;
}
View Code

修改consumer的代码:

void *consumer(void *junk)
{
    int i;
    printf("Consumer : starting\n");
    while (ch != K)
    {
        pthread_mutex_lock(&mutex);
        printf("\t Consumer : Waiting\n");
        //while(share.count != MAX){
            pthread_cond_wait(&cond, &mutex);  //条件不成立释放锁.
            printf("Consumer wating for FULL signal\n");
        //}
        printf("Consumer : getting buffer :: ");
        for(i = 0; share.buffer[i] && share.count;++i, share.count--)
            putchar(share.buffer[i]);
        putchar(\n);
        pthread_mutex_unlock(&mutex);
    }
}

编译运行会有两种结果:

一种是:

Consumer : starting
         Consumer : Waiting
Producer : starting 
Producer: put char[A]
Producer: put char[B]
Producer: put char[C]
Producer: put char[D]
Producer: put char[E]
Producer: signaling full
Consumer wating for FULL signal
Consumer : getting buffer :: ABCDE
         Consumer : Waiting
Producer: put char[F]
Producer: put char[G]
Producer: put char[H]
Producer: put char[I]
Producer: put char[J]
Producer: signaling full
Consumer wating for FULL signal
Consumer : getting buffer :: FGHIJ
Produce: Exiting 

另一种是:

Producer : starting 
Producer: put char[A]
Producer: put char[B]
Producer: put char[C]
Producer: put char[D]
Producer: put char[E]
Producer: signaling full
Consumer : starting
     Consumer : Waiting

可以看出来第二种是先执行了生产者,生产者填充满buffer之后,发送条件消息,但是此时consumer还没有执行,也并没有等待条件

然后生产者释放锁,接着消费者获取锁,然后等待条件,由于缓冲已经满,

if(share.count == MAX)

生产者不会进入发送消息的代码,所以消费者一直等待条件.

而上面一种的结果是因为,消费这先执行了,进入等待条件,所以没有这个问题,但是问题在于我们不能保证pthread_cond_wait()一定是先与pthread_cond_signal()执行的.

但是通过加while()代码,就不会出现等待条件变量的问题,可以直接执行下面的代码.

 

这个生产者消费者的解决方案是,同时只有一个生产者和消费者,是1:1的关系,生产生产完成后再让消费者过来取,消费者和生产者在各自的活动期间,对方都在等待,这种效率比较低.

 

生产者消费者问题

标签:

原文地址:http://www.cnblogs.com/biglucky/p/4643465.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!