生产者消费者模型(linux下c语言实现)

代码实现

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

/* 定义互斥锁和条件变量(静态) */
static pthread_mutex_t g_mutex  = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t  g_condition_notEmpty = PTHREAD_COND_INITIALIZER;
static pthread_cond_t  g_condition_notFull  = PTHREAD_COND_INITIALIZER;

/* ---------------------------------------------start of 实现环形buffer */

/* 实现一个环形buff,就是一个数组 */
#define CAPACITY 10

/* 全局的仓库 */
static char g_store[CAPACITY] = {'\0'};

/* 取出位置 */
static int g_outPutPosition  = 0;

/* 放入位置 */
static int g_inPutPosition  = 0;

/* 产品 */
char strData;

/* 判断环形缓冲区满 */
static int isBufferFull(void)
{
    if(g_outPutPosition == ((g_inPutPosition + 1) % CAPACITY))
        return 1;
    else
        return 0;
}

/* 判断环形缓冲区空 */
static int isBufferEmpty(void)
{
    if(g_outPutPosition == g_inPutPosition)
        return 1;
    else
        return 0;
}

/* 放入字符到环形buff */
static int putChToBuffer(char strData)
{
    /* 放入环形buff */
    g_store[g_inPutPosition] = strData;

    /* 更新放入的位置 */
    g_inPutPosition = (g_inPutPosition + 1) % CAPACITY;
    return 0;
}

/* 从环形buff取出字符 */
static int getChFromBuffer(char strData)
{
    strData = g_store[g_outPutPosition];

    /* 取出后,给它赋值为* */
    g_store[g_outPutPosition]  = '*';

    /* 更新取出的位置 */
    g_outPutPosition = (g_outPutPosition + 1) % CAPACITY;
    return 0;
}

/* ----------------------------------------end of 实现环形buffer */


void showStore(const char *who, const char *direction, char strData)
{
    int index;
    for (index = 0; index < CAPACITY; index++)
    {
        printf("%c", g_store[index]);
    }
    printf("%s %c(%s)\n", direction, strData, who);
}

/* 生产者线程 */
void *producerThreadFunc(void *arg)
{
    const char *who = (char *)arg;
    while(1)
    {
        //先获得锁
        pthread_mutex_lock(&g_mutex);

        /* 满了的话,不能再放数据 */
        if (1 == isBufferFull())
        { 
            printf("仓库满了,%s线程不能进行生产!\n", who);
            
            /* 阻塞在这,释放锁,等待被其他线程唤醒,唤醒的条件是:不满,同时释放锁 */
            pthread_cond_wait(&g_condition_notFull, &g_mutex); 
            
            /* 被唤醒之后 重新获得锁,程序往下执行 */
            printf("有人进行了消费,%s线程可以进行生产了!\n", who);
        }
        
        /* 生产者放数据 */
        strData = 'a' + rand() % 26;
        putChToBuffer(strData);
        showStore(who, " <--(input) ", strData);
        
        /* 生产者线程发送信号 */
        pthread_cond_signal(&g_condition_notEmpty);
        
        /* 释放锁 */
        pthread_mutex_unlock(&g_mutex);

        /* 延时,是为了看效果 */
        sleep(1);
        
    }
    return NULL;
}


/* 消费者线程 */
void *consumerThreadFunc(void *arg)
{
    const char *who = (const char *)arg;
    while(1)
    {
        /* 获得锁 */
        pthread_mutex_lock(&g_mutex);

        /* 判断是否为空 */
        if (1 == isBufferEmpty())
        {
            printf("仓库空了,%s等待!\n", who);

            /* 空了的时候等待,唤醒的条件是:不空 */
            pthread_cond_wait(&g_condition_notEmpty, &g_mutex);

            /* 被唤醒后,说明生产者已经放入了数据 */
            printf("----------仓库有货,%s可以消费!\n", who);
        };
        /* 消费者取数据 */
        getChFromBuffer(strData);
        showStore(who, "-->(output)", strData);
        
        pthread_cond_signal(&g_condition_notFull);
        //释放锁
        pthread_mutex_unlock(&g_mutex);
        
        sleep(1);
    }
    return NULL;
}

int main()
{
    /* 生产者 消费者各两个 */
    pthread_t producer_tid[2];
    pthread_t consumer_tid[2];
    
    pthread_create(&producer_tid[0], NULL, producerThreadFunc, "producer_1");
    pthread_create(&producer_tid[1], NULL, producerThreadFunc, "producer_2");
    pthread_create(&consumer_tid[0], NULL, consumerThreadFunc, "consumer_1");
    pthread_create(&consumer_tid[1], NULL, consumerThreadFunc, "consumer_2");

    pthread_join(producer_tid[0],NULL);
    pthread_join(producer_tid[1],NULL);
    pthread_join(consumer_tid[0],NULL);
    pthread_join(consumer_tid[1],NULL);

    getchar();
    return 0;
}

编译:gcc xxx.c -o test -lpthread

执行:./test


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潘良荣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值