使用POSIX標準中的Pthreads API來建立多個生產者、消費者線程app
定義線程:pthread_t tidpost
建立線程:pthread_create(&tid,&attr,runner,argv[1]);spa
join線程:pthread_join(tid,NULL);線程
使用PthreadsAPI的信號量機制互斥與同步code
定義信號量:sem_t sem隊列
初始化信號量:sem_init(&sem, 0, n);同步
P操做:sem_wait(&sem);產品
V操做:sem_post(&sem);it
#include <stdio.h> #include <pthread.h> #include <semaphore.h> #define BUFF_SIZE 5 // 定義緩衝區buffer大小爲5 int buffer[BUFF_SIZE]; // 用循環隊列模擬緩衝區 int in = 0; // 產品進緩衝區時的緩衝區下標 int out = 0; // 產品出緩衝區時的緩衝區下標 int productID = 0; // 產品號 int consumeID = 0; // 將被消耗的產品號 sem_t s; // 定義互斥信號量, 互斥鎖s sem_t n; // 定義同步信號量n, buffer中已放入的產品個數 sem_t e; // 定義同步信號量e, buffer中空單元個數 // 生產一個產品, 輸出新產品的ID號 void produce() { printf("成功生產了第:%d個產品\n",++productID); } // 把新生產的產品放入buffer void appen() { printf("將新生產的產品放入緩衝區\n"); buffer[in] = productID; in = (in+1)%BUFF_SIZE; int i; // 輸出緩衝區當前的狀態 for(i = 0; i<BUFF_SIZE; i++) { printf("i : %d",buffer[i]); if(i == in) printf("<-生產"); if(i == out) printf("<-消費"); printf("\n"); } printf("\n"); } // 生產者 void * Producer() { while(1) { sem_wait(&e); // 生產者首先試圖拿一個buffer空單元, 獲取一個空單元 sem_wait(&s); // 獲取互斥鎖s, 對臨界區加鎖, 互斥訪問臨界區buffer produce(); // 生產一個產品 appen(); // 把新生產的產品放入buffer Sleep(1000); // 模擬實際生產, 耗時1S sem_post(&s); // 臨界區buffer訪問完畢, 釋放互斥鎖s sem_post(&n); // 生產者任務完成, 釋放一個產品 } } // 從buffer中取出一個產品 void take() { printf("從緩衝區中取出第:%d個產品\n",++consumeID); consumeID = buffer[out]; out = (out+1)%BUFF_SIZE; int i; // 輸出緩衝區當前的狀態 for(i = 0; i<BUFF_SIZE; i++) { printf("i : %d",buffer[i]); if(i == in) printf("<-生產"); if(i == out) printf("<-消費"); printf("\n"); } } // 消耗一個產品 void consume() { printf("消費了%d個產品\n\n",consumeID); } // 消費者 void * Consumer() { while(1) { sem_wait(&n); // 消費者首先試圖拿一個buffer產品,獲取一個產品 sem_wait(&s); // 獲取互斥鎖s,對臨界區加鎖,互斥訪問臨界區buffer take(); // 從buffer中取出一個產品 consume(); // 消耗一個產品 Sleep(1000); // 模擬實際消費,耗時1S sem_post(&s); // 臨界區buffer訪問完畢,釋放互斥鎖s sem_post(&e); // 生產者任務完成,釋放一個buffer空單元 } } int main() { // 調整下面的數值,能夠發現,當生產者個數多於消費者個數時, // 生產速度快,生產者常常等待消費者;反之,消費者常常等待 // 生產者的個數 int P_COUNT = 2; // 消費者的個數 int C_COUNT = 1; pthread_t p[P_COUNT],c[C_COUNT]; // 建立各個信號 sem_init(&s,0,1); // 初始化信號量s爲互斥鎖 sem_init(&n,0,0); // 初始化信號量n:buffer中已放入的產品數目(初始爲0) sem_init(&e,0,BUFF_SIZE); // 初始化buffer中單元數目爲BUFF_SIZE int i = 0; // 建立生產者線程 for(i = 0; i < P_COUNT; i++) { pthread_create(&p[i],NULL,Producer,NULL); pthread_create(&c[i],NULL,Consumer,NULL); } // 建立消費者線程 for(i = 0; i < C_COUNT; i++) { pthread_join(p[i],NULL); pthread_join(c[i],NULL); } }
Console輸出:io
成功生產了第:1個產品
將新生產的產品放入緩衝區
i : 1<-消費
i : 0<-生產
i : 0
i : 0
i : 0
成功生產了第:2個產品
將新生產的產品放入緩衝區
i : 1<-消費
i : 2
i : 0<-生產
i : 0
i : 0
成功生產了第:3個產品
將新生產的產品放入緩衝區
i : 1<-消費
i : 2
i : 3
i : 0<-生產
i : 0
從緩衝區中取出第:1個產品
i : 1
i : 2<-消費
i : 3
i : 0<-生產
i : 0
消費了1個產品
從緩衝區中取出第:2個產品
i : 1
i : 2
i : 3<-消費
i : 0<-生產
i : 0
消費了2個產品
成功生產了第:4個產品
將新生產的產品放入緩衝區
i : 1
i : 2
i : 3<-消費
i : 4
i : 0<-生產
成功生產了第:5個產品
將新生產的產品放入緩衝區
i : 1<-生產
i : 2
i : 3<-消費
i : 4
i : 5
...
...