使用條件變數實現生產者-消費者問題,其中存在2個生產者和1個消費者
阿新 • • 發佈:2022-05-25
- 使用cond控制消費者從倉庫拿取物品
- 使用mutex控制倉庫中物品數量一次只有一個執行緒進行修改
- 倉庫使用佇列儲存,先生成的物品被先取出
#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; }
效果如下: