用條件變數和訊號量解決生產者和消費者問題
阿新 • • 發佈:2019-02-10
用條件變數解決生產者和消費者問題(只有一個緩衝區):
結果如下:
#define MAX 100 //最大操作次數 int buffer = 0; //用來記錄緩衝區中是否為空,只有一個緩衝區 Lock* mutex; Condition* condc; Condition* condp; //生產者 void Producer(int tid) { for(int i = 1;i < MAX;i++) { mutex->Acquire(); //加鎖 while(buffer != 0) condp->Wait(mutex); //如果緩衝區值不為0,緩衝區滿,等待消費者清空 buffer = i; //將緩衝區中值設為i printf("tid= %d,Produce a new item. i = %d\n",tid,i); condc->Signal(mutex); //向消費者傳送訊號 mutex->Release(); //解鎖 } } //消費者 void Consumer(int tid) { for(int i = 1; i < MAX; i++) { mutex->Acquire(); //加鎖 while(buffer == 0) condc->Wait(mutex); //當緩衝區值為0時,緩衝區為空,等待生產者 buffer = 0; //將緩衝區置為空 printf("tid = %d,Consume a item. i = %d\n",tid,i); condp->Signal(mutex); //向生產者傳送訊號 mutex->Release(); //解鎖 } } void TestPC() { mutex = new Lock("mutex"); condc = new Condition("condc"); condp = new Condition("condp"); Thread *tp = Thread::getInstance("producer thread"); if(tp != NULL) tp->Fork(Producer,tp->getTid()); //建立生產者執行緒 Thread *tc = Thread::getInstance("consumer thread"); if(tc != NULL) tc->Fork(Consumer,tc->getTid()); //建立消費者執行緒 }
結果如下:
#define MAXITEMS 10 List* list; Semaphore* smutex; Semaphore* full; Semaphore* empty; void Producer1(int tid) { int* item; int flag = 1; for(int i = 0;i < 30;i++) { item = &flag; //生產一項 printf("tid = %d, Produce a new item, item =%d\n",tid,(*item)); empty->P(); //empty - 1 smutex->P(); list->Append(item); //放入共享區域 smutex->V(); full->V(); //full + 1 } } void Consumer1(int tid) { int* item; for(int i = 0;i < 30;i++) { full->P(); //full - 1 smutex->P(); item = (int*)list->Remove(); //從共享區域中移除 smutex->V(); empty->V(); //empty + 1 *item = 0; //消費一項 printf("tid = %d, Consume a item, item =%d\n",tid,*item); } } void TestPC1() { list = new List; smutex = new Semaphore("mutex",1); //互斥訊號量 empty = new Semaphore("empty",MAXITEMS); //記錄空間中空餘數 full = new Semaphore("full",0); //記錄空間中存放數目 Thread *tp = Thread::getInstance("producer thread"); if(tp != NULL) tp->Fork(Producer1,tp->getTid()); Thread *tc = Thread::getInstance("consumer thread"); if(tc != NULL) tc->Fork(Consumer1,tc->getTid()); }
結果如下: