1. 程式人生 > >用條件變數和訊號量解決生產者和消費者問題

用條件變數和訊號量解決生產者和消費者問題

用條件變數解決生產者和消費者問題(只有一個緩衝區):

#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());            //建立消費者執行緒
}

結果如下:


利用訊號量實現生產者於消費者問題,預設快取區空間為10.List佇列用來存放生產的產品。
#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());
}

結果如下: