linux 多线程编程之——消费者与生产者

之前 在网上 搜了一堆多线程的经典的例子,其中最简单是消费者与生产者

不过 他们的代码经过测试都有段错误,原因是没有对互斥锁,条件等等初始化。以下是经过修改的代码,可以正常运行。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <string.h>
#define BUFFER_SIZE 8

struct Products
{
    int buffer[BUFFER_SIZE];
    pthread_mutex_t locker;           //保证存取操作的原子性 互斥性
    pthread_cond_t notEmpty;          //是否可读       
    pthread_cond_t notFull;          //是否可写
    int posReadFrom;
    int posWriteTo;
};
struct Products products;

int BufferIsFull(struct Products* products)
{
    if ((products->posWriteTo + 1) % BUFFER_SIZE == products->posReadFrom)
    {
        return (1);
    }
    return (0);
}

int BufferIsEmpty(struct Products* products)
{
    if (products->posWriteTo == products->posReadFrom)
    {
        return (1);
    }

    return (0);
}

//制造产品。

void Produce(struct Products* products, int item)
{
    pthread_mutex_lock(&products->locker); //原子操作
        
    while (BufferIsFull(products))
    {
        pthread_cond_wait(&products->notFull, &products->locker);
    } //无空间可写入
        
    //写入数据
    products->buffer[products->posWriteTo] = item;
    products->posWriteTo++;
        
    if (products->posWriteTo >= BUFFER_SIZE)
    {
        products->posWriteTo = 0;
    }
    pthread_cond_signal(&products->notEmpty);     //发信
    pthread_mutex_unlock(&products->locker);    //解锁
}

int Consume(struct Products* products)
{
    int item;
    
    pthread_mutex_lock(&products->locker);
    
    while (BufferIsEmpty(products))
    {
        pthread_cond_wait(&products->notEmpty, &products->locker);
    } //为空时持续等待,无数据可读
    
    //提取数据
    item = products->buffer[products->posReadFrom];
    products->posReadFrom++;
    
    if (products->posReadFrom >= BUFFER_SIZE) //如果到末尾,从头读取
    {
        products->posReadFrom = 0;
    }
    pthread_cond_signal(&products->notFull); 
    pthread_mutex_unlock(&products->locker);
    
    return item;
}


#define END_FLAG (-1)

struct Products products;

void* 
ProducerThread(void *arg)
{
    int i;
    for (i = 0; i < 16; i++)
    {
        printf("producer: %d\t", i);
        Produce(&products, i);   
    }
    Produce(&products, END_FLAG);
    return NULL;
}

void* 
ConsumerThread(void *arg)
{
    int item;
    
    while (1)
    {
        item = Consume(&products);
        if (END_FLAG == item)
            break;
    
    printf("consumer: %d\t", item);
    }
    
    return (NULL);
}
 
 void InitProducer(struct Products* products)
 {
    memset(products->buffer,0,BUFFER_SIZE);
    pthread_mutex_init(&products->locker, NULL);
    products->notEmpty = PTHREAD_COND_INITIALIZER;
    products->notFull = PTHREAD_COND_INITIALIZER;
    products->posReadFrom = 0;
    products->posWriteTo = 0;       
 }
int main(int argc, char* argv[])
{             
    pthread_t producer;
    pthread_t consumer;
    void   *result ;
    int  ret;    
    
    InitProducer(&products);   
    if ((ret= pthread_create(&producer, NULL, &ProducerThread, NULL)) != 0)
    {
        printf("producer 创建失败\n");   
    }
    else
    {
         printf("producer 创建成功\n");  
    }
    if ((ret= pthread_create(&consumer, NULL, &ConsumerThread, NULL) )!= 0)
    {
        printf("Consumer创建失败\n");   
    }
    else
    {
         printf("Consumer 创建成功\n");  
    }  
    
    
    pthread_join(producer, &result);
    pthread_join(consumer, &result);

    system("pause");
    exit(EXIT_SUCCESS);
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值