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

📄 eatingdlg.cpp

📁 计算机仿真的实验
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	      str.Format("时刻: %4d 哲学家 %d 获取筷子 %d 成功,等待筷子 %d",p->m_Time,p->m_Customer,p->Trop,l);
		  m_Process.InsertString(0,str);
		  m_Process.RedrawWindow(NULL,NULL,RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
		  m_thinker.thinkerStatus[i]=HUNGRY_STATUS;
		  ::InvalidateRect(m_thinker.m_view,m_thinker.thinkerRect[i],TRUE);
		  m_wndView.OnPaint();
	   }
	  
   }
   else
   {
	   if(m_thinker.WaitBegin[i]==0)   //如果还没有等待的话在这个时刻开始等待
		      m_thinker.WaitBegin[i]=p->m_Time; 
	   str.Format("时刻: %4d 哲学家 %d 获取筷子 %d 不成功,开始等待筷子 %d",p->m_Time,p->m_Customer,p->Trop,p->Trop);
	   m_Process.InsertString(0,str);
	   m_Process.RedrawWindow(NULL,NULL,RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
	   m_thinker.thinkerStatus[i]=HUNGRY_STATUS;
	   ::InvalidateRect(m_thinker.m_view,m_thinker.thinkerRect[i],TRUE);
	   m_wndView.OnPaint();
	   m_thinker.WaitQueue[j][m_thinker.HaveCur[j]]=i;
	   m_thinker.HaveCur[j]++;//代表等待队列的长度
   }
}
void  CEatingDlg::Departure(int i,int j,CCalendar *p)
{

	m_thinker.tropicStatus[j]=0;  //释放筷子资源
	 if(m_thinker.WaitQueue[j][0]>=0)  //如果有哲学家在等待这个筷子,那么调度这个哲学家来取
	 {
		  CCalendar *p2=new CCalendar;  //加进日程表给等待的哲学家
	      p2->m_Time=p->m_Time;
	      p2->m_Customer=m_thinker.WaitQueue[j][0];
	      p2->Trop=j;
	      p2->AorD=1;
	      Add(p2);
		  if(m_thinker.HaveCur[j]==2)
		  {
			  m_thinker.WaitQueue[j][0]=m_thinker.WaitQueue[j][1];
		  }
		  else
			  m_thinker.WaitQueue[j][0]=-1;  //恢复初始值
		  m_thinker.HaveCur[j]--;
	 }
     int temp=GetNormalTime();  //思考时间服从正态分布
	 m_thinker.ThinkTime[i]+=temp;
	 Think[i].AddTail(temp);   //每次思考的时间进入列表,备后面分析使用
     m_thinker.thinkerStatus[i]=THINKING_STATUS;
    ::InvalidateRect(m_thinker.m_view,m_thinker.userect[i],TRUE);
	::InvalidateRect(m_thinker.m_view,m_thinker.Idlerect[i],TRUE);
	::InvalidateRect(m_thinker.m_view,m_thinker.Idlerect[(i + THINKER_NUM -1)%THINKER_NUM],TRUE);
	::InvalidateRect(m_thinker.m_view,m_thinker.thinkerRect[i],TRUE);
	 m_wndView.OnPaint();
	 m_thinker.HaveTrop[i]--;
     m_thinker.HaveFree[i]++;
	 if(m_thinker.HaveFree[i]==2)//当两个都释放后
	 {
	    CCalendar *p1=new CCalendar;//调度下次i再来要j的时间,也就是思考完的时间
 	    p1->m_Time=p->m_Time+temp;
	    p1->m_Customer=i;
	    p1->Trop=(i-1+THINKER_NUM)%THINKER_NUM;
	    p1->AorD=1;
	    Add(p1);
	     
		CCalendar  *p3=new CCalendar;//再获右边的      
		p3->m_Time=p->m_Time+temp;
		p3->m_Customer=i;
	    p3->Trop=i;
		p3->AorD=1;    
		Add(p3);
	    m_thinker.HaveFree[i]=0;//复原已释放的资源数目
	 }

	 CString str;//在进度栏里加入事件
	 if(m_thinker.HaveTrop[i]==0)
	      str.Format("时刻: %4d 哲学家 %d 释放筷子 %d 开始思考!",p->m_Time,p->m_Customer,p->Trop);
	 else
		  str.Format("时刻: %4d 哲学家 %d 释放筷子 %d.",p->m_Time,p->m_Customer,p->Trop);
     m_Process.InsertString(0,str);
	 m_Process.RedrawWindow(NULL,NULL,RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
	
}
void  CEatingDlg::Arrial2(int i,int j,CCalendar *p)
{
     int temp=GetNormalTime();  //思考时间服从正态分布
	 m_thinker.ThinkTime[i]+=temp;
	 Think[i].AddTail(temp);   //每次思考的时间进入列表,备后面分析使用
     m_thinker.thinkerStatus[i]=THINKING_STATUS;
	 m_thinker.tropicStatus[j]=0;//释放完后筷子变为空闲
    ::InvalidateRect(m_thinker.m_view,m_thinker.userect[i],TRUE);
	::InvalidateRect(m_thinker.m_view,m_thinker.Idlerect[i],TRUE);
	::InvalidateRect(m_thinker.m_view,m_thinker.Idlerect[(i + THINKER_NUM -1)%THINKER_NUM],TRUE);
	::InvalidateRect(m_thinker.m_view,m_thinker.thinkerRect[i],TRUE);
	 m_wndView.OnPaint();
	 m_thinker.HaveTrop[i]--; //拥有的筷子数减一
      m_thinker.HaveFree[i]++;
	 if(m_thinker.HaveFree[i]==2)//当两个都释放后
	 {
	    CCalendar *p1=new CCalendar;//调度下次i再来要j的时间,也就是思考完的时间
 	    p1->m_Time=p->m_Time+temp;
	    p1->m_Customer=i;
	    p1->Trop=(i-1+THINKER_NUM)%THINKER_NUM;
	    p1->AorD=1;
	    Add(p1);
	     
		CCalendar  *p3=new CCalendar;//再获右边的      
		p3->m_Time=p->m_Time+temp;
		p3->m_Customer=i;
	    p3->Trop=i;
		p3->AorD=1;    
		Add(p3);
	    m_thinker.HaveFree[i]=0;//复原已释放的资源数目
	 }
	  CString str;//在进度栏里加入事件
	 if(m_thinker.HaveTrop[i]==0)
	      str.Format("时刻: %4d 哲学家 %d 释放筷子 %d 开始思考!",p->m_Time,p->m_Customer,p->Trop);
	 else
		  str.Format("时刻: %4d 哲学家 %d 释放筷子 %d.",p->m_Time,p->m_Customer,p->Trop);
     m_Process.InsertString(0,str);
	 m_Process.RedrawWindow(NULL,NULL,RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
}
void  CEatingDlg::Departure2(int i,int j,CCalendar *p)
{
	      CString  str;
	      int temp=GetEqualTime();//吃饭时间服从均匀分布
		  m_thinker.EatTime[i]+=temp;
		  Eat[i].AddTail(temp);   //每次吃饭的时间加入到用餐的列表中,备后面分析使用
		  m_thinker.thinkerStatus[i]=EATING_STATUS;
		  m_thinker.tropicStatus[j]=1;//筷子不再是空闲的
          //开始吃饭意味着等待就结束
		  int temp1;
          if(m_thinker.WaitBegin[i]!=0)  
		  {
			  temp1=p->m_Time-m_thinker.WaitBegin[i];
			  m_thinker.WaitTime[i]+=temp1;
			  Wait[i].AddTail(temp1);   // 每次等待的时间加入到等待列表中,备后面分析使用
              m_thinker.WaitBegin[i]=0 ;//重新回到初值
		  }
		  str.Format("时刻: %4d 哲学家 %d 获取筷子 %d 成功,开始吃饭!",p->m_Time,p->m_Customer,p->Trop);
		  m_Process.InsertString(0,str);
		  m_Process.RedrawWindow(NULL,NULL,RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
          ::InvalidateRect(m_thinker.m_view,m_thinker.userect[i],TRUE);
		  ::InvalidateRect(m_thinker.m_view,m_thinker.Idlerect[i],TRUE);
		  ::InvalidateRect(m_thinker.m_view,m_thinker.Idlerect[(i + THINKER_NUM -1)%THINKER_NUM],TRUE);
		  ::InvalidateRect(m_thinker.m_view,m_thinker.thinkerRect[i],TRUE);
		  m_wndView.OnPaint();
		  CCalendar *p1=new CCalendar;  //吃完饭要调度释放筷子的事件
		  p1->m_Time=p->m_Time+temp;
		  p1->m_Customer=i;
		  p1->Trop=(i-1+THINKER_NUM)%THINKER_NUM;
		  p1->AorD=0;
		  Add(p1);

		  CCalendar *p2=new CCalendar;  //右边的
		  p2->m_Time=p->m_Time+temp;
		  p2->m_Customer=i;
		  p2->Trop=i;
		  p2->AorD=0;
		  Add(p2);
}
void  CEatingDlg::Service(int i,int j,CCalendar *p)
{
	int  que;
	CString str;
	if(p->AorD)  //判断哲学家是取筷子用餐还是用完餐释放筷子
	{
	    if((m_thinker.tropicStatus[j]==0)&&(m_thinker.WaitQueue[j][0]>=0))//如果j空闲且它的排队不空
		{
		     que=m_thinker.WaitQueue[j][0];  //取出排在前面的哲学家
		
			 if(m_thinker.HaveCur[j]==2)     //如果有两个哲学家在等待j
			 {
			    m_thinker.WaitQueue[j][0]=m_thinker.WaitQueue[j][1];//移出第一个哲学家
				m_thinker.WaitQueue[j][1]=-1;
			 }
			 else
			 {
			   m_thinker.WaitQueue[j][0]=-1;  //如果只有一个哲学家在等待,就移出这个哲学家
			 }
			 m_thinker.HaveCur[j]--;  
			
			 m_thinker.HaveTrop[que]++;    //如果que这个哲学家已经获得两个筷子了就调动departure
			if(m_thinker.HaveTrop[que]==2)
			{
				Departure2(que,j,p);
			}
			else
			{
			       int  l;
	               if(que==j)
			          l=(que+4)%5;
		           else
			          l=que;
                  if(m_thinker.WaitBegin[que]==0)     //如果还没有等待的话在这个时刻开始等待
		              m_thinker.WaitBegin[que]=p->m_Time; 
	               str.Format("时刻: %4d 哲学家 %d 获取筷子 %d 成功,等待筷子 %d",p->m_Time,que,j,l);
	               m_Process.InsertString(0,str);
	               m_Process.RedrawWindow(NULL,NULL,RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
	               m_thinker.thinkerStatus[que]=HUNGRY_STATUS;
	               ::InvalidateRect(m_thinker.m_view,m_thinker.thinkerRect[que],TRUE);
	               m_wndView.OnPaint();
			}
		}
		else
		{
            if(m_thinker.tropicStatus[j]==0)  //如果筷子是空闲的
			{
			   m_thinker.HaveTrop[i]++;
			   if(m_thinker.HaveTrop[i]==2)
			   {
				   Departure2(i,j,p);
			   }
			   else
			   {
				   int  l;
	               if(p->m_Customer==j)
			          l=(p->m_Customer+4)%5;
		           else
			          l=p->m_Customer;
                  if(m_thinker.WaitBegin[i]==0)     //如果还没有等待的话在这个时刻开始等待
		              m_thinker.WaitBegin[i]=p->m_Time; 
	               str.Format("时刻: %4d 哲学家 %d 获取筷子 %d 成功,等待筷子 %d",p->m_Time,p->m_Customer,p->Trop,l);
		           m_Process.InsertString(0,str);
		           m_Process.RedrawWindow(NULL,NULL,RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
		           m_thinker.thinkerStatus[i]=HUNGRY_STATUS;
		           ::InvalidateRect(m_thinker.m_view,m_thinker.thinkerRect[i],TRUE);
		           m_wndView.OnPaint();
				   m_thinker.tropicStatus[j]=1;//筷子不再是空闲的
			   }
          
			}
			else   //表明筷子不空而它的等待队列是空的
			{
			   if(m_thinker.WaitBegin[i]==0)   //如果还没有等待的话在这个时刻开始等待
		               m_thinker.WaitBegin[i]=p->m_Time; 
	           str.Format("时刻: %4d 哲学家 %d 获取筷子 %d 不成功,开始等待筷子 %d",p->m_Time,p->m_Customer,p->Trop,p->Trop);
	           m_Process.InsertString(0,str);
	           m_Process.RedrawWindow(NULL,NULL,RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
	           m_thinker.thinkerStatus[i]=HUNGRY_STATUS;
	           ::InvalidateRect(m_thinker.m_view,m_thinker.thinkerRect[i],TRUE);
	           m_wndView.OnPaint();
			   m_thinker.WaitQueue[j][m_thinker.HaveCur[j]]=i;
	           m_thinker.HaveCur[j]++;//代表等待队列的长度     
			}
		}
	}
	else  //表明哲学家是用完餐释放筷子
	{
	    if((m_thinker.WaitQueue[j][0]>=0)) //如果筷子的等待队列不是空的
		{
		       CCalendar *p2=new CCalendar;  //加进日程表给等待的哲学家
	           p2->m_Time=p->m_Time;
	           p2->m_Customer=m_thinker.WaitQueue[j][0];
	           p2->Trop=j;
	           p2->AorD=1;
	           Add(p2);
		       if(m_thinker.HaveCur[j]==2)
		       {
			       m_thinker.WaitQueue[j][0]=m_thinker.WaitQueue[j][1];
		       }
		       else
			       m_thinker.WaitQueue[j][0]=-1;  //恢复初始值
		       m_thinker.HaveCur[j]--;
		}
		else
		{
		   m_thinker.tropicStatus[j]=0;//i释放了j,j空闲
		}
		Arrial2(i,j,p);
	}
}
int CEatingDlg::GetNormalTime()
{
	  float m_u1,m_u2,m_x1;
	  m_u1=(float)rand()/0x7fff;
	  m_u1=(float)rand()/0x7fff;
	  m_u2=(float)rand()/0x7fff;
	
	
	 float v1=2*m_u1-1;
	 float v2=2*m_u2-1;
     float W=v1*v1+v2*v2;
	 if(W<1)
	 {
	    m_x1=v1*sqrt(((-2)*log(W))/W);
	    m_x1=10+m_x1*sqrt((double)8);
		return  (int)m_x1;
	 }
	 else
		 return 10;
}
int CEatingDlg::GetEqualTime()
{
	 int  m;
	 m=rand()%11;
	 m=m+15;
	 return m;
}


void CEatingDlg::OnBnClickedButton2()
{
	// TODO: 在此添加控件通知处理程序代码
	CString str;
	int  t,e,w;
	if(m_time>0)
	{
		m_Result.ResetContent();
		str.Format("共进行了 %d 次仿真:",m_time);
		m_Result.AddString(str);
        for(int i=0;i<5;i++)
		{
		   t=Total_Think[i]/m_time;
		   e=Total_Eat[i]/m_time;
		   w=Total_Wait[i]/m_time;
		   str.Format("哲学家 %d 平均思考时间 %2d,平均吃饭时间 %2d,平均等待时间 %2d.",i,t,e,w);
		   m_Result.AddString(str);
		}
	}
	else
		MessageBox("没有仿真数据","错误");
}
void  CEatingDlg::Statistic()
{
	    int i,j,t,e,w;
        for(i=0;i<5;i++)
		{
			j=Think[i].GetSize();
			t=m_thinker.ThinkTime[i];
			if(j!=0)
			  t=t/j;
			else
			  t=0;
			Total_Think[i]+=t;
		
			j=Eat[i].GetSize();
			e=m_thinker.EatTime[i];
			if(j!=0)
			  e=e/j;
			else
			  e=0;
			Total_Eat[i]+=e;
		
			j=Wait[i].GetSize();
			w=m_thinker.WaitTime[i];
			if(j!=0)
             w=w/j;
			else
			 w=0;
			Total_Wait[i]+=w;
			
		}
}

⌨️ 快捷键说明

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