生產者-消費者問題 實現

來源:互聯網
上載者:User
// 生產者-消費者問題是一個經典的進程同步問題,該問題最早由Dijkstra提出,用以示範他提出的訊號量機制。// 在同一個進程地址空間內執行的兩個線程。生產者線程生產物品,然後將物品放置在一個空緩衝區中供消費者線程消費。// 消費者線程從緩衝區中獲得物品,然後釋放緩衝區。當生產者線程生產物品時,如果沒有空緩衝區可用,那麼生產者線程必須等待消費者線程釋放出一個空緩衝區。// 當消費者線程消費物品時,如果沒有滿的緩衝區,那麼消費者線程將被阻塞,直到新的物品被生產出來。const unsigned short int BUFFSIZE = 10;  // 緩衝區長度unsigned short int in = 0;               // 生產者生產產品進緩衝區下標unsigned short int out = 0;              // 消費者取產品出緩衝區下標unsigned short int nProductID = 0;       // 生產產品idunsigned short int nConsumeID = 0;       // 消費產品idint g_buff[BUFFSIZE] = {0};              // 緩衝區bool g_bContinue = true;                 // 控製程序結束HANDLE g_hMutex = NULL;                  // 線程同步互斥量 HANDLE g_hProducerSemaphore = NULL;      // 生產者緩衝區訊號量,滿時等待HANDLE g_hCustomerSemaphore = NULL;      // 消費者緩衝區訊號量,空時等待// 生產產品,放入隊列void Produce(){HANDLE hProducer = GetCurrentThread();TCHAR szHandle[100];_stscanf(szHandle, _T("%d"), hProducer);cout<<"The producer is " <<szHandle<<",new product id is "<<++nProductID<<", buffer index is "<<in<<endl;  // 簡化處理g_buff[in] = nProductID;in = (in+1)%BUFFSIZE;// 輸出緩衝區當前的狀態 for(int i=0; i<BUFFSIZE; i++){ cout<<i<<": "<<g_buff[i]; if(i == in){cout<<"<--生產"; }if(i == out){cout<<"<--消費"; }cout<<endl;}}// 生產者線程unsigned WINAPI ProduceThread(LPVOID param){while(g_bContinue){if(WAIT_OBJECT_0 != WaitForSingleObject(g_hProducerSemaphore, 30)){continue;}if(WAIT_OBJECT_0 != WaitForSingleObject(g_hMutex, INFINITE)) // 獲得buf使用許可權{ReleaseSemaphore(g_hProducerSemaphore, 1, NULL);continue;}Produce();Sleep(2000);ReleaseMutex(g_hMutex);ReleaseSemaphore(g_hCustomerSemaphore, 1, NULL);}return 0;}// 從緩衝區取,消費產品void Consume(){nConsumeID = g_buff[out];HANDLE hCustomer = GetCurrentThread();TCHAR szHandle[100];_stscanf(szHandle, _T("%d"), hCustomer);cout<<"-->The customer is " <<szHandle<<",consume product id is "<<nConsumeID<<", buffer index is "<<out<<endl;  // 簡化處理out = (out+1)%BUFFSIZE;// 輸出緩衝區當前的狀態 for(int i=0; i<BUFFSIZE; i++){ cout<<i<<": "<<g_buff[i]; if(i == in){cout<<"<--生產"; }if(i == out){cout<<"<--消費"; }cout<<endl;} }// 消費者線程unsigned WINAPI ConsumeThread(LPVOID param){while(g_bContinue){if(WAIT_OBJECT_0 != WaitForSingleObject(g_hCustomerSemaphore, 30)){continue;}if(WAIT_OBJECT_0 != WaitForSingleObject(g_hMutex, INFINITE)) // 獲得buf使用許可權{ReleaseSemaphore(g_hCustomerSemaphore, 1, NULL);continue;}Consume();Sleep(2000);ReleaseMutex(g_hMutex);ReleaseSemaphore(g_hProducerSemaphore, 1, NULL);}return 0;}int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]){int nRetCode = 0;// 初始化 MFC 並在失敗時顯示錯誤if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)){// TODO: 更改錯誤碼以符合您的需要_tprintf(_T("錯誤: MFC 初始化失敗\n"));nRetCode = 1;}else{// TODO: 在此處為應用程式的行為編寫代碼。g_hMutex = CreateMutex(NULL, FALSE, NULL);if (g_hMutex == NULL){cout<<_T("Create mutex error")<<endl;}g_hProducerSemaphore = CreateSemaphore(NULL, BUFFSIZE, BUFFSIZE, NULL);g_hCustomerSemaphore = CreateSemaphore(NULL, 0, BUFFSIZE, NULL);if (g_hProducerSemaphore == NULL || g_hCustomerSemaphore == NULL){cout<<_T("Create semaphore error")<<endl;}// 定義生產者和消費者線程的數量int i = 0;const int nProducerThreadNum = 3;const int nCustomerTHreadNum = 1;HANDLE haProducer[nProducerThreadNum];HANDLE haCustomer[nCustomerTHreadNum];HANDLE hTmp = NULL;for (i=0; i<nProducerThreadNum; i++){haProducer[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ProduceThread, NULL, 0, NULL);}for (i=0; i<nCustomerTHreadNum; i++){haCustomer[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ConsumeThread, NULL, 0, NULL);}if(getchar()){// 任意鍵退出g_bContinue = false;}DWORD dwWaitProducer = WaitForMultipleObjects(nProducerThreadNum, (const HANDLE*)haProducer, TRUE, INFINITE);DWORD dwWaitCustomer = WaitForMultipleObjects(nCustomerTHreadNum, (const HANDLE*)haCustomer, TRUE, INFINITE);for (i=0; i<nProducerThreadNum; i++){CloseHandle(haProducer[i]);}for (i=0; i<nCustomerTHreadNum; i++){CloseHandle(haCustomer[i]);}CloseHandle(g_hMutex);CloseHandle(g_hProducerSemaphore);CloseHandle(g_hCustomerSemaphore);}return nRetCode;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.