1. 程式人生 > 其它 >使用條件變數實現生產者-消費者問題,其中存在2個生產者和1個消費者

使用條件變數實現生產者-消費者問題,其中存在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;
}

效果如下: