1. 程式人生 > >作業系統-使用訊號量實現生產者與消費者(C++實現)

作業系統-使用訊號量實現生產者與消費者(C++實現)

常用函式:

HANDLE WINAPI CreateSemaphore(               
  _In_opt_  LPSECURITY_ATTRIBUTES lpSemaphoreAttributes
  _In_      LONG lInitialCount,
  _In_      LONG lMaximumCount,
  _In_opt_  LPCTSTR lpName
);
第一個引數:安全屬性,如果為NULL則是預設安全屬性
第二個引數:訊號量的初始值,要>=0且<=第三個引數
第三個引數:訊號量的最大值
第四個引數:訊號量的名稱

返回值:指向訊號量的控制代碼,如果建立的訊號量和已有的訊號量重名,那麼返回已經存在的訊號量控制代碼

DWORD WaitForSingleObject(  

 HANDLE hHandle,   

 DWORD dwMilliseconds

);

第一個引數:等待物件的 handle(代表一個核心物件)。

第二個引數:等待的最長時間。時間終了,即使 handle尚未成為激發狀態,此函式也要返回。此值可以是0(代表立刻返回),也可以是 INFINITE代表無窮等待。

BOOL WINAPI ReleaseSemaphore(             
  _In_       HANDLE hSemaphore,
  _In_       LONG lReleaseCount,
  _Out_opt_  LPLONG lpPreviousCount
);
第一個引數:訊號量控制代碼
第二個引數:釋放後,訊號量增加的數目
第三個引數:訊號量增加前的值存放的地址,如果不需要則為NULL
返回值:釋放是否成功

生產者與消費者的實現:

#include<string>
 #include<iostream>
 #include<process.h>
 #include<windows.h>
 using namespace std;
 HANDLE empty,full; //同步訊號量 緩衝池的剩餘 緩衝池中的產品個數 生產者與消費者同步
 HANDLE mutex;//互斥訊號量,生產者與生產者互斥,消費者與消費者互斥
 int buf_max;       //緩衝池大小
 int product=0;     //產品數量
//生產者執行緒
unsigned __stdcall threadProducer(void *)
{
    for(int i = 0; i < 10; i++){
        WaitForSingleObject(empty, INFINITE);//等待同步訊號量empty
        WaitForSingleObject(mutex, INFINITE);//等待互斥訊號量mutex
        product++;
        cout<<"生產者生產了一個產品!當前產品數量:"<<product<<endl<<endl;
        Sleep(100);
        ReleaseSemaphore(mutex, 1, NULL);//釋放互斥訊號量mutex
        ReleaseSemaphore(full, 1, NULL);//釋放同步訊號量full
    }
    return 1;
}
//消費者執行緒
unsigned __stdcall threadConsumer(void *)
{
    for(int i = 0; i < 10; i++){
        WaitForSingleObject(full, INFINITE);//等待同步訊號量full
        WaitForSingleObject(mutex, INFINITE);//等待互斥訊號量mutex
        product--;
        cout<<"消費者消費了一個產品!當前產品數量:"<<product<<endl<<endl;
        Sleep(100);
        ReleaseSemaphore(mutex, 1, NULL);//釋放互斥訊號量mutex
        ReleaseSemaphore(empty, 1, NULL);//釋放訊號量
    }
    return 2;
}
 
int main()
{
    bool flag=false;
    while(!flag)
    {
    cout<<"請輸入緩衝池大小(大於0):"<<endl;
    cin>>buf_max;
    if(buf_max<=0);
    else flag=true;
    }
    //建立訊號量
    empty = CreateSemaphore(NULL, buf_max, buf_max, NULL);//初值為緩衝池大小,最大為緩衝池大小
    full = CreateSemaphore(NULL, 0, buf_max, NULL);       //初值為0,最大為緩衝池大小
    mutex = CreateSemaphore(NULL,1,1,NULL);               //初值為1,最大為1
    HANDLE hth1, hth2;                                    //執行緒控制代碼
 
    //建立執行緒
    hth1 = (HANDLE)_beginthreadex(NULL, 0, threadProducer, NULL, 0, NULL);//生產者執行緒
    hth2 = (HANDLE)_beginthreadex(NULL, 0, threadConsumer, NULL, 0, NULL);//消費者執行緒
 
    //等待子執行緒結束
    WaitForSingleObject(hth1, INFINITE);
    WaitForSingleObject(hth2, INFINITE);
 
    //一定要記得關閉控制代碼
    CloseHandle(hth1);
    CloseHandle(hth2);
    CloseHandle(empty);
    CloseHandle(full);
    CloseHandle(mutex);
}