zoukankan      html  css  js  c++  java
  • LINUX学习:生产者&消费者模型复习

    回顾一下生产者消费者模型。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <semaphore.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <pthread.h>
    #define ERR_EXIT(m) 
        do { 
            perror(m);
            exit(EXIT_FAILURE);
        }while(0)
    #define CONSUMERS_COUNT 1
    #define PRODUCERS_COUNT 2
    #define BUFFSIZE 10
    
    int g_buffer[BUFFSIZE];
    
    unsigned short in = 0;
    unsigned short out = 0;
    unsigned short product_id = 0;
    unsigned short consume_id = 0;
    
    sem_t g_sen_full;
    sem_t g_sen_empty;
    pthread_mutex_t g_mutex;
    
    pthread_t g_thread[CONSUMERS_COUNT+PRODUCERS_COUNT];
    
    void* consume(void* arg)
    {
        int i;
        while(1)
        {
            sem_wait(&g_sen_empty);
            pthread_mutex_lock(&g_mutex);
            for (i = 0; i < BUFFSIZE; ++i)
            {
                /* code */
                printf("%02d
    ", i);
                if(g_buffer[i] == -1)
                    printf("%s", "null");
                else
                    printf("%d
    ", g_buffer[i]);
                if(i == out)
                    printf("	<--consume
    ");
                printf("
    ");
            }
            consume_id = g_buffer[out];
            printf("begin consume product %d
    ", consume_id);
            g_buffer[out] = -1;
            out = (out + 1) % BUFFSIZE;
            pthread_mutex_unlock(&g_mutex);
            sem_post(&g_sen_full);
            sleep(1);
        }
        return NULL;
    }
    void* produce(void *arg)
    {
        int num = (int)arg;
        int i;
        while(1)
        {
            printf("%d waiting buffer_full
    ", num);
            sem_wait(&g_sen_full);
            pthread_mutex_lock(&g_mutex);
            for (i = 0; i < BUFFSIZE; ++i)
            {
                /* code */
                printf("%02d
    ", i);
                if(g_buffer[i] == -1)
                    printf("%s", "null");
                else
                    printf("%d
    ", g_buffer[i]);
                if(i == in)
                    printf("	<--produce
    ");
                printf("
    ");
            }
            printf("begin produce product %d
    ", product_id);
            g_buffer[in] = product_id;
            in = (in +1) % BUFFSIZE;
            printf("end produce product %d
    ", product_id++);
            pthread_mutex_unlock(&g_mutex);
            sem_post(&g_sen_empty);
        }
        return NULL;
    }
    int main(int argc, const char *argv[])
    {
        int i;
        for (i = 0; i < BUFFSIZE; ++i)
        {
            /* code */
            g_buffer[i] = -1;
        }
        // 初始化信号量
        sem_init(&g_sen_full, 0, BUFFSIZE);
        sem_init(&g_sen_empty, 0, 0);
        // 初始化锁
        pthread_mutex_init(&g_mutex, NULL);
    
        for (i = 0; i < CONSUMERS_COUNT; ++i)
        {
            /* code */
            pthread_create(&g_thread[i], NULL, consume, (void*)i);
        }
            for (i = 0; i < PRODUCERS_COUNT; ++i)
        {
            /* code */
            pthread_create(&g_thread[CONSUMERS_COUNT+i], NULL, produce, (void*)i);
        }
            for (i = 0; i < CONSUMERS_COUNT+PRODUCERS_COUNT; ++i)
        {
            /* code */
            pthread_join(g_thread[i], NULL);
        }
    
        sem_destroy(&g_sen_empty);
    
        sem_destroy(&g_sen_full);
        pthread_mutex_destroy(&g_mutex);  
        return 0;
    }

    东莞东方

    再写一个 条件变量的版本。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <semaphore.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <pthread.h>
    #define ERR_EXIT(m) 
        do { 
            perror(m);
            exit(EXIT_FAILURE);
        }while(0)
    #define CONSUMERS_COUNT 2
    #define PRODUCERS_COUNT 1
    #define BUFFSIZE 10
    
    
    
    unsigned short in = 0;
    unsigned short out = 0;
    unsigned short product_id = 0;
    unsigned short consume_id = 0;
    
    sem_t g_sen_full;
    sem_t g_sen_empty;
    pthread_mutex_t g_mutex;
    pthread_cond_t g_cond;
    pthread_t g_thread[CONSUMERS_COUNT+PRODUCERS_COUNT];
    
    int nready = 0;
    
    void* consume(void* arg)
    {
        int num = (int)arg;
        while(1)
        {
            pthread_mutex_lock(&g_mutex);
            while(nready==0)
            {
                printf("begin wait a condtion
    ");
                 pthread_cond_wait(&g_cond, &g_mutex);
            }
    
            printf("no.%dend of wait a condtion ....
    ", num);
            --nready;
            printf("消费者%d消耗一个产品
    ", num);
            pthread_mutex_unlock(&g_mutex);
    
        }
        return NULL;
    }
    void* produce(void *arg)
    {
        int num = (int)arg;
        while(1)
        {
            pthread_mutex_lock(&g_mutex);
            ++nready;
            printf("生产者%d生产了一个产品并发送signal..
    ", num);
            pthread_cond_signal(&g_cond);
            pthread_mutex_unlock(&g_mutex);
            sleep(5);
        }
        return NULL;
    }
    int main(int argc, const char *argv[])
    {
        int i;
        pthread_mutex_init(&g_mutex, NULL);
        pthread_cond_init(&g_cond, NULL);
    
        for (i = 0; i < CONSUMERS_COUNT; ++i)
        {
            /* code */
            pthread_create(&g_thread[i], NULL, produce, (void*)i);
        }
        for (i = 0; i < PRODUCERS_COUNT; ++i)
        {
            /* code */
            pthread_create(&g_thread[i+CONSUMERS_COUNT], NULL, consume, (void*)i);
        }
        for (i = 0; i < CONSUMERS_COUNT+PRODUCERS_COUNT; ++i)
        {
            /* code */
            pthread_join(g_thread[i], NULL);
        }
        pthread_mutex_destroy(&g_mutex);
        pthread_cond_destroy(&g_cond);
        return 0;
    }

    pthread_cond_wait这个函数的原语:

    一。对g_mutex进行解锁,让其他线程可以进入临界区

    二。等待条件,直到有线程可以唤醒它,然后让出CPU

    三。当被唤醒时,它会重新对g_mutex进行加锁

    对于生产者&消费者进行判断为啥使用while而不是if,我们已经之前讨论过了

    if值判断一次,而重新上锁之后并不能保证它还满足情况。

  • 相关阅读:
    面向对象-类
    模块04
    总结
    昨天的新的解决方法
    感冒了~ vs中py和vb实现一个小算法
    vs2015社区版不支持installshield
    网站被黑了
    2018/11/18(python)
    2018/11/14
    2018/11/12(python)
  • 原文地址:https://www.cnblogs.com/DLzhang/p/4341821.html
Copyright © 2011-2022 走看看