zoukankan      html  css  js  c++  java
  • 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. }   
  • 相关阅读:
    Selenium2+python自动化-使用JS脚本处理网页滚动条
    Python定时框架 Apscheduler 详解【转】
    转:VMware 15 安装 MAC OS 10.13 原版(详细图文教程)
    Appium+Robotframework实现iOS应用的自动化测试
    在jenkins打开roboframework报告:Opening Robot Framework report failed
    springcloud使用pagehelper 实现分页,及total 数据问题
    日志打印request 和response 内容
    springboot+elasticsearch + rabbitMQ实现全文检索(使用transportClient 实现CRUD)
    springboot+elasticsearch + rabbitMQ实现全文检索(springboot+ES整合)
    springboot+elasticsearch + rabbitMQ实现全文检索(项目搭建)
  • 原文地址:https://www.cnblogs.com/zhangyunlin/p/6168137.html
Copyright © 2011-2022 走看看