生產者消費者問題

參考地址:http://blog.csdn.net/morewindows/article/details/7577591ios

生產者消費者問題是一個著名的線程同步問題,該問題描述以下:有一個生產者在生產產品,這些產品將提供給若干個消費者去消費,爲了使生產者和消費者能併發執行,在二者之間設置一個具備多個緩衝區的緩衝池,生產者將它生產的產品放入一個緩衝區中,消費者能夠從緩衝區中取走產品進行消費,顯然生產者和消費者之間必須保持同步,即不容許消費者到一個空的緩衝區中取產品,也不容許生產者向一個已經放入產品的緩衝區中再次投放產品。windows

代碼一:1個生產者,1個消費者,1個緩衝區併發

 1 #include <iostream>
 2 #include <Windows.h>
 3 #include <process.h>
 4 using namespace std;
 5 /************************************************************************************
 6 
 7                             模擬單個緩衝區的狀況
 8 
 9 *************************************************************************************/
10 const int PRODUCT_NUM = 10; //生產產品個數
11 int g_nBuffer;                //緩衝區
12 CRITICAL_SECTION g_cs;
13 HANDLE g_hEventBufferEmpty;
14 HANDLE g_hEventBufferFull;
15 
16 //設置控制檯文字顏色
17 BOOL SetConsoleColor(WORD wAttributes)
18 {
19     HANDLE hHandle = GetStdHandle(STD_OUTPUT_HANDLE);
20     if (hHandle == INVALID_HANDLE_VALUE)
21     {
22         cout << "GetStdHandle Error!" << endl;
23         return false;
24     }
25     //SetConsoleTitle(L"生產者消費者問題");
26     return SetConsoleTextAttribute(hHandle, wAttributes);
27 }
28 
29 unsigned int WINAPI ProducerThreadFunc(PVOID pParam)
30 {
31     for (int i = 1; i <= PRODUCT_NUM; ++i)
32     {
33         if (i > PRODUCT_NUM)
34         {
35             return 0;
36         }
37         WaitForSingleObject(g_hEventBufferEmpty, INFINITE);
38         EnterCriticalSection(&g_cs);
39         g_nBuffer = i;
40         SetConsoleColor(FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED);
41         cout << "生產者將數據[" << i << "]放入緩衝區!" << endl;
42         LeaveCriticalSection(&g_cs);
43         SetEvent(g_hEventBufferFull);
44     }
45     return 0;
46 }
47 
48 unsigned int WINAPI ConsumerThreadFunc(PVOID pParam)
49 {
50     //volatile bool bFlag = true;
51     while(true)
52     {
53         WaitForSingleObject(g_hEventBufferFull, INFINITE);
54         EnterCriticalSection(&g_cs);
55         SetConsoleColor(FOREGROUND_GREEN);
56         cout << "消費者從緩衝區中取出數據[" << g_nBuffer << "]" << endl;
57         SetConsoleColor(FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN);
58         if (g_nBuffer == PRODUCT_NUM)
59         {
60             LeaveCriticalSection(&g_cs);
61             return 0;
62         }
63         Sleep(100);
64         LeaveCriticalSection(&g_cs);
65         SetEvent(g_hEventBufferEmpty);
66     }
67     return 0;
68 }
69 
70 int main()
71 {
72     const int nThreadNum = 2;
73     HANDLE hThread[nThreadNum];
74     g_hEventBufferEmpty = CreateEvent(NULL, false, true, NULL);
75     g_hEventBufferFull = CreateEvent(NULL, false, false, NULL);
76     InitializeCriticalSection(&g_cs);
77 
78     cout << "\t\t生產者消費者問題:1生產者,1消費者,1緩衝區" << endl;
79     hThread[0] = (HANDLE)_beginthreadex(NULL, 0, ProducerThreadFunc, NULL, 0, NULL);
80     hThread[1] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFunc, NULL, 0, NULL);
81     WaitForMultipleObjects(nThreadNum, hThread, true, INFINITE);
82     
83     CloseHandle(hThread[0]);
84     CloseHandle(hThread[1]);
85     CloseHandle(g_hEventBufferFull);
86     CloseHandle(g_hEventBufferEmpty);
87     DeleteCriticalSection(&g_cs);
88 
89     return 0;
90 }

代碼二:1個生成者,2個消費者,4個緩衝區spa

  1 #include <iostream>
  2 #include <Windows.h>
  3 #include <process.h>
  4 using namespace std;
  5 /************************************************************************************
  6 
  7                         模擬多個緩衝區、多個消費者的狀況
  8 
  9 *************************************************************************************/
 10 const int PRODUCT_NUM = 10; //生產產品個數
 11 const int BUFFERSIZE = 4;    //緩衝區個數
 12 int g_nBuffer[BUFFERSIZE];
 13 int g_nProduceCnt;    //生產位置
 14 int g_nConsumeCnt;    //消費位置
 15 CRITICAL_SECTION g_cs;
 16 HANDLE g_hSemaphoreEmpty;
 17 HANDLE g_hSemaphoreFull;
 18 
 19 //設置控制檯文字顏色
 20 BOOL SetConsoleColor(WORD wAttributes)
 21 {
 22     HANDLE hHandle = GetStdHandle(STD_OUTPUT_HANDLE);
 23     if (hHandle == INVALID_HANDLE_VALUE)
 24     {
 25         cout << "GetStdHandle Error!" << endl;
 26         return false;
 27     }
 28     //SetConsoleTitle(L"生產者消費者問題");
 29     return SetConsoleTextAttribute(hHandle, wAttributes);
 30 }
 31 
 32 unsigned int WINAPI ProducerThreadFunc(PVOID pParam)
 33 {
 34     for (int i = 1; i <= PRODUCT_NUM; ++i)
 35     {//生產者與消費者之間本不該該互斥,可是這裏考慮到設置控制檯顏色的問題,必須互斥,實際狀況這裏的互斥條件應該去掉
 36         WaitForSingleObject(g_hSemaphoreEmpty, INFINITE);
 37         EnterCriticalSection(&g_cs);
 38         g_nProduceCnt = (i-1)%BUFFERSIZE;
 39         g_nBuffer[g_nProduceCnt] = i;
 40         SetConsoleColor(FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED);
 41         cout << "生產者[" << GetCurrentThreadId() << "]將數據[" << i << "]放入緩衝區位置[" << g_nProduceCnt << "]" << endl;
 42         LeaveCriticalSection(&g_cs);
 43         ReleaseSemaphore(g_hSemaphoreFull, 1, NULL);
 44     }
 45     return 0;
 46 }
 47 
 48 unsigned int WINAPI ConsumerThreadFunc(PVOID pParam)
 49 {
 50     volatile bool bFlag = true;
 51     while(bFlag)
 52     {
 53         WaitForSingleObject(g_hSemaphoreFull, INFINITE);
 54         EnterCriticalSection(&g_cs);
 55         if (!bFlag)
 56         {
 57             LeaveCriticalSection(&g_cs);
 58             return 0;
 59         }
 60         SetConsoleColor(FOREGROUND_GREEN);
 61         cout << "消費者[" << GetCurrentThreadId() << "]從緩衝區中位置[" << g_nConsumeCnt%BUFFERSIZE << "]取出數據[" << 
                g_nBuffer[g_nConsumeCnt%BUFFERSIZE] << "]" << endl; 62 ++g_nConsumeCnt; 63 SetConsoleColor(FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN); 64 if (g_nConsumeCnt == PRODUCT_NUM) 65 { 66 LeaveCriticalSection(&g_cs); 67 bFlag = false; 68 } 69 Sleep(100); 70 LeaveCriticalSection(&g_cs); 71 ReleaseSemaphore(g_hSemaphoreEmpty, 1, NULL); 72 } 73 return 0; 74 } 75 76 int main() 77 { 78 const int nThreadNum = 3; 79 HANDLE hThread[nThreadNum]; 80 81 g_hSemaphoreEmpty = CreateSemaphore(NULL, 4, BUFFERSIZE, NULL); 82 g_hSemaphoreFull = CreateSemaphore(NULL, 0, BUFFERSIZE, NULL); 83 InitializeCriticalSection(&g_cs); 84 85 g_nProduceCnt = 0; 86 g_nConsumeCnt = 0; 87 cout << "\t\t生產者消費者問題:1生產者,2消費者,4緩衝區" << endl; 88 hThread[0] = (HANDLE)_beginthreadex(NULL, 0, ProducerThreadFunc, NULL, 0, NULL); 89 hThread[1] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFunc, NULL, 0, NULL); 90 hThread[2] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFunc, NULL, 0, NULL); 91 WaitForMultipleObjects(nThreadNum, hThread, true, INFINITE); 92 93 for (int i = 0; i < nThreadNum; ++i) 94 CloseHandle(hThread[i]); 95 CloseHandle(g_hSemaphoreFull); 96 CloseHandle(g_hSemaphoreEmpty); 97 DeleteCriticalSection(&g_cs); 98 99 return 0; 100 }
相關文章
相關標籤/搜索