生产者消费者的c语言版本实现

//代码可直接编译通过

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#define MAX_STOCK 20//容量
char g_storage[MAX_STOCK];
size_t g_stock = 0;//当前库存
pthread_mutex_t g_mtx = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t g_full = PTHREAD_COND_INITIALIZER;
pthread_cond_t g_empty = PTHREAD_COND_INITIALIZER;
void show(const char* who,const char* op,char prod){
    printf("%s:",who);
    size_t i;
    for(i < 0;i < g_stock;++i)
        printf("%c",g_storage[i]);
    printf("%s%c\n",op,prod);
}
void* producer(void* arg)
{
    const char* who = (const char*)arg;
    for(;;){
        pthread_mutex_lock(&g_mtx);
        while(g_stock >= MAX_STOCK){//此处必须用while判断,防止条件失效。试想两个producer都阻塞在
            //wait上,之后一个被唤醒。生产之后,另一个又返回去生产,导致越界。
            printf("%s:full\n",who);
            pthread_cond_wait(&g_full,&g_mtx);
            //此函数阻塞,同时Mutex会解锁,返回之前需重新获取这把锁
        }
        char prod = 'A' + rand()%26;
        show(who,"<-",prod);
        g_storage[g_stock++] = prod;
        pthread_cond_broadcast(&g_empty);
        pthread_mutex_unlock(&g_mtx);
        usleep((rand()%100)*1000);
    }
    return NULL;
}
void* customer(void* arg){
    const char* who = (const char*)arg;
    for(;;){
        pthread_mutex_lock(&g_mtx);
        while(!g_stock){
            printf("%s:空仓\n",who);
            pthread_cond_wait(&g_empty,&g_mtx);
            //g_empty初始化之后无信号,之后进入阻塞.
        }
        char prod = g_storage[--g_stock];
        show(who,"->",prod);
        pthread_cond_broadcast(&g_full);//只有有线程阻塞的时候发信号才有效.
        pthread_mutex_unlock(&g_mtx);
        usleep((rand()%100)*1000);
    }
    return NULL;
}
int main(void){
    srand(time(NULL));
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
    pthread_t tid;
    pthread_create(&tid,&attr,producer,"prodecer1");
    pthread_create(&tid,&attr,producer,"prodecer2");
    pthread_create(&tid,&attr,customer,"customer1");
    pthread_create(&tid,&attr,customer,"customer2");
    getchar();
}

//pthread_cond_broadcast(&g_full)叫醒所有的,pthread_cond_signal(&g_full)只唤醒一个

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值