Windows线程(生产者与消费者问题)

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. }   
原文地址:https://www.cnblogs.com/zhangyunlin/p/6168137.html