同步中有一個稱為生產者-消費者問題的經典問題,也稱為有界緩沖區問題。一個或多個生產者(線程或進程)
創建着一個個的數據條目,然后這些數據條目有一個或多個消費者(線程或進程)處理。數據條目在生產者和消
費者之間是使用某種類型的IPC傳遞的。
而在我們的單個消費者和單個生產者之間的問題中,使用互斥鎖和條件變量使其同步。而互斥鎖用於上鎖,條
件變量則用於等待。在程序中定義了如下的結構體:
typedef struct pc_st { int buffer[BUFFER_SIZE]; pthread_mutex_t mutex; pthread_cond_t notfull; pthread_cond_t notempty; int write_pos; int read_pos; }pc_st;
在結構體中定義了一個數組用於存儲產品,定義了互斥變量,定義了兩個條件變量,定義了兩個位置,當生產
產品時和消費產品時用於判斷數組中是否是滿的還是空的。
之后定義的結構體變量對其進行初始化,在程序中,主要有兩個函數去實現生產和消費功能,put()函數是實現
生產者生產產品的函數,而get()函數是實現消費者進行消費產品的函數。
下面是運用互斥鎖和條件變量來實現生產者消費者問題的代碼:
#include <stdio.h> #include <unistd.h> #include <pthread.h> #define BUFFER_SIZE 8 #define MAX_COUNT 20 typedef struct pc_st { int buffer[BUFFER_SIZE]; pthread_mutex_t mutex; pthread_cond_t notfull; pthread_cond_t notempty; int write_pos; int read_pos; }pc_st; #define OVER -1 #define PC_ST_INITIALIZER {{OVER,OVER,OVER,OVER,OVER,OVER,OVER,OVER},PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER,PTHREAD_COND_INITIALIZER,0,0} pc_st pc= PC_ST_INITIALIZER; void put(int data) { pthread_mutex_lock(&pc.mutex); if((pc.write_pos+ 1)%BUFFER_SIZE== pc.read_pos) pthread_cond_wait(&pc.notfull,&pc.mutex); pc.buffer[pc.write_pos]= data; pc.write_pos= (pc.write_pos+ 1)%BUFFER_SIZE; pthread_cond_signal(&pc.notempty); pthread_mutex_unlock(&pc.mutex); } int get() { int value; pthread_mutex_lock(&pc.mutex); if(pc.read_pos== pc.write_pos) pthread_cond_wait(&pc.notempty,&pc.mutex); value= pc.buffer[pc.read_pos]; pc.read_pos= (pc.read_pos+ 1)%BUFFER_SIZE; pthread_cond_signal(&pc.notfull); pthread_mutex_unlock(&pc.mutex); return value; } void* producer(void *arg) { int i= 1; while(i<= MAX_COUNT) { put(i); i++; } put(OVER); } void* consumer(void *arg) { int value; while(1) { value= get(); if(value== OVER) break; printf("value= %d\n",value); sleep(1); } } int main() { pthread_t pro_id,con_id; pthread_create(&pro_id,NULL,producer,NULL); pthread_create(&con_id,NULL,consumer,NULL); pthread_join(pro_id,NULL); pthread_join(con_id,NULL); return 0; }