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

📄 3.txt

📁 CreateSemaphore #include <stdlib>
💻 TXT
字号:
一个生产者一个消费者进程,使用轮换法使这两个进程轮换执行。   
  #include   <windows>   
  #include   <stdlib>   
  #include   <iostream>   
  #include   <conio>   
      
  using   namespace   std;   
    
  #define   MAX_SIZE   200   
    
  char   buffer[MAX_SIZE];   
  int   in=0;   
  int   out=0;   
  int   counter=0;   
  int   inUse=0;   
    
  DWORD   WINAPI   Producer(LPVOID);   
  DWORD   WINAPI   Consumer(LPVOID);   
    
  int   main()   
  {   
          HANDLE   hTrd;   
          DWORD   ThreadId;   
    
          hTrd=CreateThread(NULL,0,Producer,(LPVOID)('A'),0,&TreadId);   
          if(hTrd)   
          {   
                    cout   <<   "thread   function   "   <<   'a'   <<"   Lunched"<<endl;   
          }   
          hTrd=CreateThread(NULL,0,Consumer,NULL,0,&TreadId);   
    
          Sleep(2000);   
          getch();   
          return   0;   
  }   
    
  DWORD   WINAPI   Producer(LPVOID   m)   
  {   
          while(1)   
          {   
                    if(inUse==0)   
                    {   
                            buffer[in++]=(char)m;   
                            in%=MAX_SIZE;   
                            cout   <<   "in"   <<   (char)m   <<   endl;   
                            inUse=1;//(1)   
                    }   
                  //(1)   
          }   
  }   
    
  DWORD   WINAPI   Producer(LPVOID   m)   
  {   
          char   m;   
          while(1)   
          {   
                    if(inUse==1)   
                    {   
                            m=buffer[out++];   
                            out%=MAX_SIZE;   
                            cout   <<   in   <<   out   <<   counter   <<   inUse   <<   endl;   
                            inUse=0;//(2)   
                    }   
                  //(2)   
          }   
  }   
    
  这样写的程序可以保证两个进程轮换执行,可是如果把两个进程中对inUse变量的修改放到另一个位置就不能实现这个功能。例如将inUse=1;//(1)放在//(1)的位置,就不能保证轮换执行,消费进程能多次进入buffer。请各位帮我看一下为什么会这样? 
例如将inUse=1;//(1)放在//(1)的位置,就不能保证轮换执行,消费进程能多次进入buffer。请各位帮我看一下为什么会这样?   
  ----------------------------------------   
    
  做这样的改变后,Producer每次检查inUse,无论是否成功,他都会将inUse设置为1,那么考虑这样的情况:   Producer执行完对inUse的检测(失败,此时Consumer在if语句块内),然后系统调度Consumer,等到Consumer执行完inUse=0;然后系统调度Producer,Producer执行inUse=1;,此时Producer将继续检测失败,而Consumer可以继续执行if语句块的内容
哦,有些明白了。在Producer中的if(inUse==0)应该汇编成两条语句,一条是判断inUse==0,一条是跳转到inUse=1;(在失败的情况下)。如果Producer正好执行完判断语句,正要执行跳转语句时时间片到,那么开始执行consumer,Consumer执行完inUse=0,后自己进入判断,知道时间片结束。然后Producer执行inUse=1,这样Producer又进入等待,而Consumer就满足条件继续进行。   
  这样是不是因为inUse也是一个临界资源,应该放到临界区中去?   
    
  谢谢fflush的解答

⌨️ 快捷键说明

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