1. 條件變量+互斥鎖 實現 生產者-消費者模型:數組
/*藉助條件變量模擬 生產者-消費者 問題*/ #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <stdio.h> /*鏈表做爲公享數據,需被互斥量保護*/ //模擬籮筐 struct msg { struct msg *next; int num; }; struct msg *head; struct msg *mp; /* 靜態初始化 一個條件變量 和 一個互斥量*/ pthread_cond_t has_product = PTHREAD_COND_INITIALIZER; //條件變量靜態初始化 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; //互斥鎖靜態初始化 void *consumer(void *p)//消費者 { for (;;) { pthread_mutex_lock(&lock);//加鎖 while (head == NULL) { //頭指針爲空,說明沒有節點 能夠爲if嗎 pthread_cond_wait(&has_product, &lock); } mp = head; head = mp->next; //模擬消費掉一個產品 pthread_mutex_unlock(&lock);//解鎖 printf("-Consume ---%d\n", mp->num); free(mp); mp = NULL; sleep(rand() % 5); } } void *producer(void *p)//生產者 { for (;;) { mp = malloc(sizeof(struct msg)); mp->num = rand() % 1000 + 1; //模擬生產一個產品 printf("-Produce ---%d\n", mp->num); pthread_mutex_lock(&lock);//加鎖 mp->next = head;//頭插法 head = mp; pthread_mutex_unlock(&lock);//解鎖 pthread_cond_signal(&has_product); //將等待在該條件變量上的一個線程喚醒 sleep(rand() % 5); } } int main(int argc, char *argv[]) { pthread_t pid, cid; srand(time(NULL)); pthread_create(&pid, NULL, producer, NULL);//建立生產者線程 pthread_create(&cid, NULL, consumer, NULL);//建立消費者線程 pthread_join(pid, NULL);//回收線程 pthread_join(cid, NULL); return 0; }
2. 信號量 實現 生產者-消費者模型:post
/*信號量實現 生產者 消費者問題*/ #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <stdio.h> #include <semaphore.h> #define NUM 5 int queue[NUM]; //全局數組實現環形隊列 sem_t blank_number, product_number; //空格子信號量, 產品信號量 void *producer(void *arg) { int i = 0; while (1) { sem_wait(&blank_number); //生產者將空格子數--,爲0則阻塞等待 queue[i] = rand() % 1000 + 1; //生產一個產品,存入隊列 printf("----Produce---%d\n", queue[i]); sem_post(&product_number); //將產品數++ i = (i+1) % NUM; //藉助下標實現環形,下標日後移 sleep(rand()%3); } } void *consumer(void *arg) { int i = 0; while (1) { sem_wait(&product_number); //消費者將產品數--,爲0則阻塞等待 printf("-Consume---%d\n", queue[i]); queue[i] = 0; //消費一個產品 sem_post(&blank_number); //消費掉之後,將空格子數++ i = (i+1) % NUM; sleep(rand()%3); } } int main(int argc, char *argv[]) { pthread_t pid, cid; sem_init(&blank_number, 0, NUM); //初始化空格子信號量爲5 sem_init(&product_number, 0, 0); //產品數爲0 pthread_create(&pid, NULL, producer, NULL); //建立生產者線程 pthread_create(&cid, NULL, consumer, NULL); //建立消費者線程 pthread_join(pid, NULL); //回收線程 pthread_join(cid, NULL); sem_destroy(&blank_number); //銷燬信號量 sem_destroy(&product_number); return 0; }