Windows線程(生產者與消費者問題)

來源:互聯網
上載者:User

Windows線程(生產者與消費者問題) 轉載 佟強 2008.10.10

     生產者-消費者問題是一個經典的進程同步問題,該問題最早由Dijkstra提出,用以示範他提出的訊號量機制。在同一個進程地址空間內執行的兩個線程。生產者線程生產物品,然後將物品放置在一個空緩衝區中供消費者線程消費。消費者線程從緩衝區中獲得物品,然後釋放緩衝區。當生產者線程生產物品時,如果沒有空緩衝區可用,那麼生產者線程必須等待消費者線程釋放出一個空緩衝區。當消費者線程消費物品時,如果沒有滿的緩衝區,那麼消費者線程將被阻塞,直到新的物品被生產出來。

  1. #include <windows.h> 
  2. #include <iostream> 
  3. const unsigned short SIZE_OF_BUFFER = 10; //緩衝區長度 
  4. unsigned short ProductID = 0; //產品號 
  5. unsigned short ConsumeID = 0; //將被消耗的產品號 
  6. unsigned short in = 0; //產品進緩衝區時的緩衝區下標 
  7. unsigned short out = 0; //產品出緩衝區時的緩衝區下標 
  8. int g_buffer[SIZE_OF_BUFFER]; //緩衝區是個迴圈隊列 
  9. bool g_continue = true; //控製程序結束 
  10. HANDLE g_hMutex; //用於線程間的互斥 
  11. HANDLE g_hFullSemaphore; //當緩衝區滿時迫使生產者等待 
  12. HANDLE g_hEmptySemaphore; //當緩衝區空時迫使消費者等待 
  13. DWORD WINAPI Producer(LPVOID); //生產者線程 
  14. DWORD WINAPI Consumer(LPVOID); //消費者線程 
  15. int main() 
  16.  //建立各個互斥訊號 
  17.  g_hMutex = CreateMutex(NULL,FALSE,NULL); 
  18.  g_hFullSemaphore = CreateSemaphore(NULL,SIZE_OF_BUFFER-1,SIZE_OF_BUFFER-1,NULL); 
  19.  g_hEmptySemaphore = CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL); 
  20.  //調整下面的數值,可以發現,當生產者個數多於消費者個數時, 
  21.  //生產速度快,生產者經常等待消費者;反之,消費者經常等待 
  22.  const unsigned short PRODUCERS_COUNT = 3; //生產者的個數 
  23.  const unsigned short CONSUMERS_COUNT = 1; //消費者的個數 
  24.  //總的線程數 
  25.  const unsigned short THREADS_COUNT = PRODUCERS_COUNT+CONSUMERS_COUNT; 
  26.  HANDLE hThreads[PRODUCERS_COUNT]; //各線程的handle 
  27.  DWORD producerID[CONSUMERS_COUNT]; //生產者線程的標識符 
  28.  DWORD consumerID[THREADS_COUNT]; //消費者線程的標識符 
  29.  //建立生產者線程 
  30.  for (int i=0;i<PRODUCERS_COUNT;++i){ 
  31.   hThreads[i]=CreateThread(NULL,0,Producer,NULL,0,&producerID[i]); 
  32.   if (hThreads[i]==NULL) return -1; 
  33.  } 
  34.  //建立消費者線程 
  35.  for (int i=0;i<CONSUMERS_COUNT;++i){ 
  36.   hThreads[PRODUCERS_COUNT+i]=CreateThread(NULL,0,Consumer,NULL,0,&consumerID[i]); 
  37.   if (hThreads[i]==NULL) return -1; 
  38.  } 
  39.  while(g_continue){ 
  40.   if(getchar()){ //按斷行符號後終止程式運行 
  41.    g_continue = false; 
  42.   } 
  43.  } 
  44.  return 0; 
  45. //生產一個產品。簡單類比了一下,僅輸出新產品的ID號 
  46. void Produce() 
  47.  std::cerr << "Producing " << ++ProductID << " ... "; 
  48.  std::cerr << "Succeed" << std::endl; 
  49. //把新生產的產品放入緩衝區 
  50. void Append() 
  51.  std::cerr << "Appending a product ... "; 
  52.  g_buffer[in] = ProductID; 
  53.  in = (in+1)%SIZE_OF_BUFFER; 
  54.  std::cerr << "Succeed" << std::endl; 
  55.  //輸出緩衝區當前的狀態 
  56.  for (int i=0;i<SIZE_OF_BUFFER;++i){ 
  57.   std::cout << i <<": " << g_buffer[i]; 
  58.   if (i==in) std::cout << " <-- 生產"; 
  59.   if (i==out) std::cout << " <-- 消費"; 
  60.   std::cout << std::endl; 
  61.  } 
  62. //從緩衝區中取出一個產品 
  63. void Take() 
  64.  std::cerr << "Taking a product ... "; 
  65.  ConsumeID = g_buffer[out]; 
  66.  out = (out+1)%SIZE_OF_BUFFER; 
  67.  std::cerr << "Succeed" << std::endl; 
  68.  //輸出緩衝區當前的狀態 
  69.  for (int i=0;i<SIZE_OF_BUFFER;++i){ 
  70.   std::cout << i <<": " << g_buffer[i]; 
  71.   if (i==in) std::cout << " <-- 生產"; 
  72.   if (i==out) std::cout << " <-- 消費"; 
  73.   std::cout << std::endl; 
  74.  } 
  75. //消耗一個產品 
  76. void Consume() 
  77.  std::cerr << "Consuming " << ConsumeID << " ... "; 
  78.  std::cerr << "Succeed" << std::endl; 
  79. //生產者 
  80. DWORD WINAPI Producer(LPVOID lpPara) 
  81.  while(g_continue){ 
  82.   WaitForSingleObject(g_hFullSemaphore,INFINITE); 
  83.   WaitForSingleObject(g_hMutex,INFINITE); 
  84.   Produce(); 
  85.   Append(); 
  86.   Sleep(1500); 
  87.   ReleaseMutex(g_hMutex); 
  88.   ReleaseSemaphore(g_hEmptySemaphore,1,NULL); 
  89.  } 
  90.  return 0; 
  91. //消費者 
  92. DWORD WINAPI Consumer(LPVOID lpPara) 
  93.  while(g_continue){ 
  94.   WaitForSingleObject(g_hEmptySemaphore,INFINITE); 
  95.   WaitForSingleObject(g_hMutex,INFINITE); 
  96.   Take(); 
  97.   Consume(); 
  98.   Sleep(1500); 
  99.   ReleaseMutex(g_hMutex); 
  100.   ReleaseSemaphore(g_hFullSemaphore,1,NULL); 
  101.  } 
  102.  return 0; 
  103. }   
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.