作業系統-使用訊號量實現生產者與消費者(C++實現)
阿新 • • 發佈:2019-01-27
常用函式:
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); }