⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sx3.cpp

📁 VC++实现生产者与消费者关系!(操作系统OS)
💻 CPP
字号:
  /*————————————————————————————————
  在同一个进程地址空间内执行的两个线程。生产者线程生产物品,
  然后将物品放置在一个空缓冲区中供消费者线程消费。消费者线
  程从缓冲区中获得物品,然后释放缓冲区。当生产者线程生产物
  品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者
  线程释放出一个空缓冲区。当消费者线程消费物品时,如果没有
  满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出
  来。
——————————————————————————————————*/
  #include<windows.h>   
  #include<iostream.h>
  #include<stdio.h>   
    
  const   unsigned   short   SIZE_OF_BUFFER   =   10;   //缓冲区长度   
  unsigned   short   ProductID   =   0;         //产品号   
  unsigned   short   ConsumeID   =   0;         //将被消耗的产品号   
  unsigned   short   in   =   0;             //产品进缓冲区时的缓冲区下标   
  unsigned   short   out   =   0;             //产品出缓冲区时的缓冲区下标   
    
  int   g_buffer[SIZE_OF_BUFFER];         //缓冲区是个循环队列   
  bool   g_continue   =   true;             //使程序跳出循环,控制程序结束   
  HANDLE   g_hMutex;               //用于线程间的互斥   
  HANDLE   g_hFullSemaphore;           //当缓冲区满时迫使生产者等待   
  HANDLE   g_hEmptySemaphore;           //当缓冲区空时迫使消费者等待   
    
  DWORD   WINAPI   Producer(LPVOID);         //生产者线程   
  DWORD   WINAPI   Consumer(LPVOID);         //消费者线程   
    
  int   main()   
  {   
          //创建各个互斥信号   
          g_hMutex   =   CreateMutex(NULL,FALSE,NULL);  // 三个参数分别为:指向安全属性的指针 
												//初始化互斥对象的所有者,指向互斥对象名的指针
          //创建缓冲区满的信号量
          g_hFullSemaphore   =   CreateSemaphore(NULL,SIZE_OF_BUFFER-1,SIZE_OF_BUFFER-1,NULL); 
														//四个参数分别为:表示是否允许继承、
														//设置信号机的初始计数、设置信号机的
		  												//最大计数、指定信号机对象的名称(-1是因为计数从0开始)
          //创建缓冲区空的信号量
		  g_hEmptySemaphore   =   CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL);   
    
          //调整下面的数值,可以发现,当生产者个数多于消费者个数时,   
          //生产速度快,生产者经常等待消费者;反之,消费者经常等待     
          const   unsigned   short   PRODUCERS_COUNT   =   3;     //生产者的个数   
          const   unsigned   short   CONSUMERS_COUNT   =   3;     //消费者的个数   
    
          //总的线程数   
          const   unsigned   short   THREADS_COUNT   =   PRODUCERS_COUNT+CONSUMERS_COUNT;   
    
          HANDLE   hThreads[PRODUCERS_COUNT];   //各线程的handle   
          DWORD   producerID[CONSUMERS_COUNT];   //生产者线程的标识符   
          DWORD   consumerID[THREADS_COUNT];   //消费者线程的标识符   
    
          //为每一个生产者创建生产者线程   
          for(int i=0;i<PRODUCERS_COUNT;++i){
                  hThreads[i]=CreateThread(NULL,0,Producer,NULL,0,&producerID[i]);   
                  if   (hThreads[i]==NULL)   return   -1;   
          }   
          //为每一个消费者创建消费者线程   
          for(int j=0;j<CONSUMERS_COUNT;++j){   
                  hThreads[PRODUCERS_COUNT+j]=CreateThread(NULL,0,Consumer,NULL,0,&consumerID[j]);   
                  if   (hThreads[j]==NULL)   return   -1;   
          }   
    
          while(g_continue){   
                  if(getchar()){   //按回车后终止程序运行   
                          g_continue   =   false;   
                  }   
          }   
    
          return   0;   
  }   
    
  //生产一个产品。简单模拟了一下,仅输出新产品的ID号   
  void   Produce()   
  {   
	      cerr   <<   "-------------------------------------------------------------------\n";
		  cerr   <<   "生产一个产品       编号为: "   <<   ++ProductID   <<   "   ...   "<<endl;   

  }   
    
  //把新生产的产品放入缓冲区   
  void   Append()   
  {   
          cerr   <<   "\n把新生产的产品放入缓冲区   ...   "<<'\n';   
          g_buffer[in]   =   ProductID;   
          in   =   (in+1)%SIZE_OF_BUFFER;   //把下一个生产的产品放入下一个缓冲区
    
          //输出缓冲区当前的状态 
		  cout   <<"\n显示缓冲区当前的状态:\n\n";
		  cout   <<"\n缓冲区编号 产品编号\n";
          for   (int   i=0;i<SIZE_OF_BUFFER;++i){
                  cout   <<"缓冲区"<<   i   <<":       "   <<   g_buffer[i];   
                  if   (i==in)   cout   <<   "   <--   生产";   
                  if   (i==out)   cout   <<   "   <--   消费";   
                  cout   <<   endl;   
          }   
  }   
    
  //从缓冲区中取出一个产品   
  void   Take()   
  {   
	      cerr   <<   "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
          cerr   <<   "从缓冲区中取出一个产品   产品编号为:"<<out+1<<'\n';   
          ConsumeID   =   g_buffer[out];  
		  g_buffer[out]=0;
          out   =   (out+1)%SIZE_OF_BUFFER;
		  
          //输出缓冲区当前的状态   
		  cout   <<"\n显示缓冲区当前的状态:\n\n";
		  cout   <<"\n缓冲区编号 产品编号\n";
          for   (int   i=0;i<SIZE_OF_BUFFER;++i){   
                  cout   <<"缓冲区"<<    i   <<":      "   <<   g_buffer[i];   
                  if   (i==in)   cout   <<   "   <--   生产";   
                  if   (i==out)   cout   <<   "   <--   消费";   
                  cout   <<   endl;   
          }   
  }   
    
  //消耗一个产品   
  void   Consume()   
  {   
          cerr   <<   "\n消耗产品   "   <<   ConsumeID   <<   "   ...   \n";   
  }   
    
  //生产者   
  DWORD     WINAPI   Producer(LPVOID   lpPara)   
  {   
          while(g_continue){   
                  WaitForSingleObject(g_hFullSemaphore,INFINITE);  //第一个参数hHandle是事件g_hFullSemaphore的句柄,
																   //第二个参数是时间间隔 ,当为
																   //INFINITE时函数将直到相应时间
																   //事件变成有信号状态才返回,否则
																   //就一直等待下去,直到g_hFullSemaphore
																   //有返回直才执行后面的代码
                  WaitForSingleObject(g_hMutex,INFINITE);   
                  Produce();   
                  Append();   
                  Sleep(1500);   
                  ReleaseMutex(g_hMutex);  //释放互斥体的所属权 
                  ReleaseSemaphore(g_hEmptySemaphore,1,NULL);   //增加信号量
          }   
          return   0;   
  }   
    
  //消费者   
  DWORD     WINAPI   Consumer(LPVOID   lpPara)   
  {   
          while(g_continue){   
                  WaitForSingleObject(g_hEmptySemaphore,INFINITE);   
                  WaitForSingleObject(g_hMutex,INFINITE);   
                  Take();   
                  Consume();   
                  Sleep(1500);   
                  ReleaseMutex(g_hMutex);   
                  ReleaseSemaphore(g_hFullSemaphore,1,NULL);   
          }   
          return   0;   
  }   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -