使用条件变量实现生产者-消费者问题,其中存在2个生产者和1个消费者

  1. 使用cond控制消费者从仓库拿取物品
  2. 使用mutex控制仓库中物品数量一次只有一个线程进行修改
  3. 仓库使用队列存储,先生成的物品被先取出
#include <func.h>

typedef struct Node_t{
    int val;
    struct Node_t *next;
}Node;

typedef struct listNode_t{
    int size;
    Node* front;
    Node* tail;
}listNode;

typedef struct Pro_Cus
{
    listNode* que;
    pthread_mutex_t mutex;
    pthread_cond_t cond;
}pro_cus_t;

void producter1(void* arg)
{
    pro_cus_t* p = (pro_cus_t*)arg;
    while(1)
    {
        //生产一个产品
        Node* newNode = (Node*)malloc(sizeof(Node));
        newNode->val = rand() % 100 + 1;
        newNode->next = NULL;
        printf("> produce1: %d\n", newNode->val);

        //准备将产品放入仓库
        pthread_mutex_lock(&p->mutex);
        if(p->que->size == 0){
            p->que->front = p->que->tail = newNode;
            p->que->size = 1;
        }
        else{
            p->que->tail->next = newNode;
            p->que->tail = newNode;
            p->que->size++;
        }
        pthread_mutex_unlock(&p->mutex);

        //通知消费者取产品
        pthread_cond_signal(&p->cond);
        sleep(rand() % 5);
    }
}

void producter2(void* arg)
{
    pro_cus_t* p = (pro_cus_t*)arg;
    while(1)
    {
        //生产一个产品
        Node* newNode = (Node*)malloc(sizeof(Node));
        newNode->val = rand() % 100 + 1;
        newNode->next = NULL;
        printf("> produce2: %d\n", newNode->val);

        //准备将产品放入仓库
        pthread_mutex_lock(&p->mutex);
        if(p->que->size == 0){
            p->que->front = p->que->tail = newNode;
            p->que->size = 1;
        }
        else{
            p->que->tail->next = newNode;
            p->que->tail = newNode;
            p->que->size++;
        }
        pthread_mutex_unlock(&p->mutex);

        //通知消费者取产品
        pthread_cond_signal(&p->cond);
        sleep(rand() % 5);
    }
}

void consumer(void* arg)
{
    pro_cus_t* q = (pro_cus_t*)arg;
    while(1)
    {
        pthread_mutex_lock(&q->mutex);
        Node* delNode;
        while(q->que->size == 0)
        {
            //没得产品,等生产者生产
            pthread_cond_wait(&q->cond,&q->mutex);
        }

        //取到产品
        delNode = q->que->front;
        printf(">> consumer: %d\n", delNode->val);
        q->que->front = q->que->front->next;
        q->que->size--;
        free(delNode);

        pthread_mutex_unlock(&q->mutex);
        sleep(rand() % 5);
    }
}

int main(int argc, char* argv[])
{
    srand(time(NULL));
    pro_cus_t resource;

    resource.que = (listNode*)malloc(sizeof(listNode));
    resource.que->size = 0;
    resource.que->front = resource.que->tail = (Node*)malloc(sizeof(Node));

    pthread_mutex_init(&resource.mutex, NULL);
    pthread_cond_init(&resource.cond, NULL);

    pthread_t pid[2], cid;
    int ret;
    ret = pthread_create(&pid[0], NULL, (void*)producter1, (void*)&resource);
    THREAD_ERR_CHECK(ret,"pthread_create1");
    ret = pthread_create(&pid[1], NULL, (void*)producter2, (void*)&resource);
    THREAD_ERR_CHECK(ret, "pthread_create2");

    ret = pthread_create(&cid, NULL, (void*)consumer, (void*)&resource);
    THREAD_ERR_CHECK(ret, "pthread_create_cus");

    pthread_join(pid[0], NULL);
    pthread_join(pid[1], NULL);
    pthread_join(cid, NULL);

    pthread_mutex_destroy(&resource.mutex);
    pthread_cond_destroy(&resource.cond);

    return 0;
}

效果如下:
image

posted @ 2022-05-25 20:13  star酱酱  阅读(86)  评论(0编辑  收藏  举报