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


    代码实现

    #include
    #include
    #include
    #include
    #include

    /* 定义互斥锁和条件变量(静态) */
    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


     

  • 相关阅读:
    【正点原子I.MX6U-MINI应用篇】4、嵌入式Linux关于GPIO的一些操作
    2021.09青少年软件编程(Python)等级考试试卷(二级)
    Bridge 桥接模式简介与 C# 示例【结构型2】【设计模式来了_7】
    手把手教你使用Git管理你的软件代码
    对话框如何屏蔽ok和cancel按键 2023/10/21 上午11:36:08
    浙江大学工程师学院非全日制定向工程管理【125601】招生问答
    (续)SSM整合之springmvc笔记(RESTful之HiddenHttpMethodFilter源码解析)(P147)了解
    剑指Offer || 041.数据流中的移动平均值
    并发编程面试笔记
    详解欧拉计划第227题:追赶游戏
  • 原文地址:https://blog.csdn.net/qrsxtkf/article/details/125898822