zoukankan      html  css  js  c++  java
  • Linux 生产者消费者简单例子学习

    #if 0
        Linux实现生产者消费者模型
        1. 防止虚假唤醒
        2. 唤醒线程的时机很重要,否则会导致线程多次访问锁,影响性能
    #endif
    
    #include <unistd.h>
    #include <stdio.h>
    #include <iostream>
    #include <pthread.h>
    
    using namespace std;
    
    int g_value = 0;
    
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
    
    void* consumer1(void* arg)
    {
        printf("consumer[%d] begin consume.
    ", (int)(*((int*)(arg))));
        pthread_mutex_lock(&mutex);
        printf("consumer[%d] pthread_mutex_lock.
    ", (int)(*((int*)(arg))));
        while (g_value <= 0) {//防止虚假唤醒
            printf("consumer[%d] begin wait.
    ", (int)(*((int*)(arg))));
            int ret = pthread_cond_wait(&cond, &mutex);
            if (ret) {
                printf("pthread_cond_wait error ret[%d].
    ", ret);
                return NULL;
            }
            printf("consumer[%d] end wait.
    ", (int)(*((int*)(arg))));
        }
        --g_value;
        printf("consumer[%d] g_value:[%d].
    ", (int)(*((int*)(arg))), g_value);
        pthread_mutex_unlock(&mutex);
        printf("consumer[%d] pthread_mutex_unlock.
    ", (int)(*((int*)(arg))));
        return NULL;
    }
    
    void* consumer2(void* arg)
    {
        printf("consumer[%d] begin consume.
    ", (int)(*((int*)(arg))));
        pthread_mutex_lock(&mutex);
        printf("consumer[%d] pthread_mutex_lock.
    ", (int)(*((int*)(arg))));
        while (g_value <= 0) {//防止虚假唤醒
            printf("consumer[%d] begin wait.
    ", (int)(*((int*)(arg))));
            int ret = pthread_cond_wait(&cond, &mutex);
            if (ret) {
                printf("pthread_cond_wait error ret[%d].
    ", ret);
                return NULL;
            }
            printf("consumer[%d] end wait.
    ", (int)(*((int*)(arg))));
        }
        --g_value;
        printf("consumer[%d] g_value:[%d].
    ", (int)(*((int*)(arg))), g_value);
        pthread_mutex_unlock(&mutex);
        printf("consumer[%d] pthread_mutex_unlock.
    ", (int)(*((int*)(arg))));
        return NULL;
    }
    
    void* producer(void* arg)
    {
        cout << "producer begin product." << endl;
        pthread_mutex_lock(&mutex);
        printf("producer pthread_mutex_lock.
    ");
        ++g_value;
        cout << "producer g_value: " << g_value << endl;
        if (g_value > 0) {
            cout << "producer begin pthread_cond_broadcast." << endl;
            int ret = pthread_cond_broadcast(&cond);
            if (ret) {
                printf("pthread_cond_broadcast error ret[%d].
    ", ret);
                return NULL;
            }
            cout << "producer end pthread_cond_broadcast." << endl;
        }
        printf("producer begin pthread_mutex_unlock.
    ");
        int ret = pthread_mutex_unlock(&mutex);
        if (ret) {
            printf("pthread_mutex_unlock error ret[%d].
    ", ret);
            return NULL;
        }
        printf("producer end pthread_mutex_unlock.
    ");
        return NULL;
    }
    
    int join(pthread_t tid, void **retval)
    {
        int ret = pthread_join(tid, retval);
        if (ret) {
            return ret;
        }
        else {
            return 0;
        }
    }
    
    int main()
    {
        pthread_t tid_consumer[2] = {0};
        pthread_t tid_producer = 0;
        int ret = -1;
        int _consumer1 = 1;
        ret = pthread_create(&tid_consumer[0], NULL, &consumer1, (void*)(&_consumer1));
        if (ret) {
            printf("pthread_create error ret[%d].
    ", ret);
            return -1;
        }
        sleep(1);
        int _consumer2 = 2;
        ret = pthread_create(&tid_consumer[1], NULL, &consumer2, (void*)(&_consumer2));
        if (ret) {
            printf("pthread_create error ret[%d].
    ", ret);
            return -1;
        }
    
        sleep(5);
        ret = pthread_create(&tid_producer, NULL, &producer, NULL);
        if (ret)
        {
            printf("pthread_create error ret[%d].
    ", ret);
            return -1;
        }
        sleep(2);
    
        for (int i = 0; i < sizeof(tid_consumer)/sizeof(tid_consumer[0]); ++i)
        {
            ret = join(tid_consumer[i], NULL);
            if (ret) {
                printf("join error ret[%d].
    ", ret);
            }
        }
        ret = join(tid_producer, NULL);
        if (ret) {
            printf("join error ret[%d].
    ", ret);
            return -1;
        }
        printf("pthread join success.
    ");
    
        return 0;
    }
  • 相关阅读:
    系统调用与库函数
    在树莓派上 搭建sqlite数据库
    (转)inux Read系统调用
    查看当前日期是这一年的第几天
    求解某个范围内的全部完数
    求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。
    输入三个整数x,y,z,请把这三个数据由大到小输出。
    模仿ArrayList底层实现
    可视化日历
    Oracle之约束条件1:主键约束
  • 原文地址:https://www.cnblogs.com/chen-cai/p/11382643.html
Copyright © 2011-2022 走看看