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

📄 eatingdlg.cpp

📁 计算机仿真的实验
💻 CPP
📖 第 1 页 / 共 3 页
字号:
				#ifdef DEBUGING
				TRACE("the %d ID is eating\n ",ID);
				#endif

				m_ph->thinkerStatus[ID] = EATING_STATUS;
				
				m_ph->tropicStatus[(ID + THINKER_NUM -1)%THINKER_NUM] = 1;
				m_ph->tropicStatus[ID] = 1;

				::InvalidateRect(m_ph->m_view,m_ph->userect[ID],TRUE);
				::InvalidateRect(m_ph->m_view,m_ph->Idlerect[ID],TRUE);
				::InvalidateRect(m_ph->m_view,m_ph->Idlerect[(ID + THINKER_NUM -1)%THINKER_NUM],TRUE);
				::InvalidateRect(m_ph->m_view,m_ph->thinkerRect[ID],TRUE);
								

				Sleep(800 +25*(m_ph->m_speed) + GetRandTime());
				

				//cast the tropic and continue to think
					m_ph->thinkerStatus[ID] = THINKING_STATUS;
				m_ph->tropicStatus[(ID + THINKER_NUM -1)%THINKER_NUM] = 0;
				m_ph->tropicStatus[ID] = 0;
				::InvalidateRect(m_ph->m_view,m_ph->userect[ID],TRUE);
				::InvalidateRect(m_ph->m_view,m_ph->Idlerect[ID],TRUE);
				::InvalidateRect(m_ph->m_view,m_ph->Idlerect[(ID + THINKER_NUM -1)%THINKER_NUM],TRUE);
				::InvalidateRect(m_ph->m_view,m_ph->thinkerRect[ID],TRUE);
				ReleaseMutex(m_ph->tropics[(ID + THINKER_NUM -1)%THINKER_NUM]);
				ReleaseMutex(m_ph->tropics[ID]);
				
				TRACE(" the %d ID is exiting ",ID);
				
				
		}	
	m_ph->ThinkerCnt--;
	m_ph->thinkerStatus[ID] = NORMAL_STATUS;
	::InvalidateRect(m_ph->m_view,m_ph->thinkerRect[ID],TRUE);
	if(m_ph->ThinkerCnt == -1)
		ResetEvent(m_ph->ThreadExit);
	return 1;
}

void CEatingDlg::OnBtnBegin() 
{
	int i;
	if(!m_HasInit)
		InitStruct();
	m_beginBtn.EnableWindow(FALSE);
    m_wndView.m_pthinker=&m_thinker;
	m_wndView.OnPaint();
	UpdateData();
   //先把所有的时间清零
   for(i = 0;i<THINKER_NUM;i++)
	{
		m_thinker.ThinkTime[i]=0;
		m_thinker.EatTime[i]=0;
		m_thinker.WaitTime[i]=0;
		m_thinker.HaveTrop[i]=0;
		m_thinker.HaveCur[i]=0;
		m_thinker.WaitQueue[i][0]=-1;
		m_thinker.HaveFree[i]=0;
		m_thinker.WaitBegin[i]=0;
		Eat[i].RemoveAll();
		Think[i].RemoveAll();
		Wait[i].RemoveAll();
	}
	m_thinker.HaveTrop[1]=2;//因为2和4初始时都占有两个筷子
	m_thinker.HaveTrop[3]=2;
	Clock=0;
   if(m_Strategy==1)
   {
	  int  temp_Cus,temp_Trop;
	  srand( (unsigned)time( NULL ) );
      InitList();
	  m_time++;
	  m_Process.ResetContent();
	  m_wndView.m_pthinker=&m_thinker;
	  CCalendar  *p=(CCalendar*)CA_List.GetAt(0);//每次都是取日程表的第一个数
	  while(CA_List.GetSize()>0&&p->m_Time<m_Clock)
	  {
		  CA_List.RemoveAt(0);
		  Clock=p->m_Time;                           //走动时钟
		  temp_Cus=p->m_Customer;
		  temp_Trop=p->Trop;
		  if(p->AorD==1)
		  {   
			  Arrial(temp_Cus,temp_Trop,p);
		  }
		  else
		  {
			  Departure(temp_Cus,temp_Trop,p);
		  }
		  Sleep(m_thinker.m_speed*10);
		 p=(CCalendar*)CA_List.GetAt(0);
	  }
	  Statistic();
	  m_beginBtn.EnableWindow(TRUE);
   }
   else
   {
    if(m_Strategy==2)
	{
	  srand( (unsigned)time( NULL ) );
      InitList();
	  m_time++;
	  m_Process.ResetContent();
	  m_wndView.m_pthinker=&m_thinker;
	  CCalendar  *p=(CCalendar*)CA_List.GetAt(0);//每次都是取日程表的第一个数
	  while(CA_List.GetSize()>0&&p->m_Time<m_Clock)
	  {
		  CA_List.RemoveAt(0);
		  Clock=p->m_Time;                           //走动时钟
		  Service(p->m_Customer,p->Trop,p);
		  Sleep(m_thinker.m_speed*10);
		 p=(CCalendar*)CA_List.GetAt(0);
	  }
	  Statistic();
	  m_beginBtn.EnableWindow(TRUE);
	}
	else
	{
	   for(i = 0;i<THINKER_NUM;i++)
	  {		
		  m_thinker.ThinkerCnt++;
		  AfxBeginThread(Eating,(PVOID)&m_thinker);
		  Sleep(50);
	  }
	
    }
   }
	m_stopBtn.EnableWindow(TRUE);
	//m_beginBtn.EnableWindow(FALSE);
	//m_okBtn.EnableWindow(FALSE);
	m_HasInit=false;
}


void CEatingDlg::OnBtnStop() 
{
	SetEvent(m_thinker.ThreadExit);
	BeginWaitCursor();
	while(WaitForSingleObject(m_thinker.ThreadExit,500) == WAIT_OBJECT_0);
	for(int i = 0;i<THINKER_NUM;i++)
		CloseHandle(m_thinker.tropics[i]);         //初始化MUTEX变量		
	CloseHandle(m_thinker.ThreadExit);
	EndWaitCursor();
	m_okBtn.EnableWindow(TRUE);
	m_beginBtn.EnableWindow(TRUE);
	m_stopBtn.EnableWindow(FALSE);
	m_HasInit = FALSE;
}

void CEatingDlg::OnOK() 
{

	TRACE("%d ",(-1)%5);
	CDialog::OnOK();
}

void CEatingDlg::OnDestroy() 
{
	CDialog::OnDestroy();
	
	font.DeleteObject();	
}

void CEatingDlg::OnOutofmemorySlider1(NMHDR* pNMHDR, LRESULT* pResult) 
{
	*pResult = 0;
}

void CEatingDlg::OnCustomdrawSlider1(NMHDR* pNMHDR, LRESULT* pResult) 
{

	UpdateData();	
	m_thinker.m_speed = 100 - m_AdjustSpeed.GetPos();	
	UpdateData(FALSE);
	
	*pResult = 0;
}

void CEatingDlg::OnButton1() 
{
    int i,j,t,e,w;
	CString  str;
	m_Result.ResetContent();
	if(Think[0].GetSize()>0)
	{
	    for(i=0;i<5;i++)
		{
			j=Think[i].GetSize();
			t=m_thinker.ThinkTime[i];
			t=t/j;
			j=Eat[i].GetSize();
			e=m_thinker.EatTime[i];
			e=e/j;
			j=Wait[i].GetSize();
			w=m_thinker.WaitTime[i];
			if(j!=0)
             w=w/j;
			else
			  w=0;
			str.Format("哲学家 %d 平均思考时间 %2d,平均吃饭时间 %2d,平均等待时间 %2d.",i,t,e,w);
			m_Result.AddString(str);
		}
	}
	else
	   MessageBox("还没有仿真的数据","错误");
}

void CEatingDlg::OnBnClickedOk()
{
	// TODO: 在此添加控件通知处理程序代码
	OnOK();
}

void CEatingDlg::OnBnClickedRadio1()
{
	// TODO: 在此添加控件通知处理程序代码
	m_Strategy=1;
}

void CEatingDlg::OnBnClickedRadio2()
{
	// TODO: 在此添加控件通知处理程序代码
	m_Strategy=2;
}

void CEatingDlg::OnBnClickedRadio3()
{
	// TODO: 在此添加控件通知处理程序代码
	m_Strategy=3;
}
void   CEatingDlg::InitList()
{
   int temp;
   for(int i = 0;i<THINKER_NUM;i++)
	{		
		if(m_thinker.thinkerStatus[i]==THINKING_STATUS)//如果哲学家在思考
		{
		    temp=GetNormalTime();     //获取思考的时间
			m_thinker.ThinkTime[i]+=temp;
			Think[i].AddTail(temp);   //每次思考的时间进入列表,备后面分析使用
            CCalendar  *p=new CCalendar;
			p->m_Time=temp;
			p->m_Customer=i;  //哲学家只能获取相邻的筷子
			p->AorD=1;        //表示哲学家要获得这个筷子,进入筷子的队列
			p->Trop=(i-1+THINKER_NUM)%THINKER_NUM;//先获取左边的筷子
			Add(p);
			CCalendar  *p1=new CCalendar;//再获右边的      
			p1->m_Time=temp;
			p1->m_Customer=i;  
			p1->AorD=1;  
			p1->Trop=i;  
            Add(p1);
		}
		else
		{
		  if(m_thinker.thinkerStatus[i]==EATING_STATUS)//如果哲学家在吃饭
		  {
		    temp=GetEqualTime();
			m_thinker.EatTime[i]+=temp;
			Eat[i].AddTail(temp);   //每次吃饭的时间加入到用餐的列表中,备后面分析使用
			CCalendar  *p=new CCalendar;
			p->m_Time=temp;
			p->m_Customer=i;  
			p->AorD=0;                           //表示哲学家吃完要释放筷子
			p->Trop=(i-1+THINKER_NUM)%THINKER_NUM;//先释放左边的筷子
			Add(p);
			CCalendar  *p1=new CCalendar;//再释放右边的筷子      
			p1->m_Time=temp;
			p1->m_Customer=i;  
			p1->AorD=0;  
			p1->Trop=i;  
            Add(p1);
		  }
		}
	}
}
void  CEatingDlg::Add(CCalendar *p)//按照时间顺序添加到日程表中
{
	CCalendar  *ptemp;
	CA_List.Add((CCalendar*)p);
	int m_Size=CA_List.GetSize();
	int i;
	for(i=m_Size-1;i>0;i--)
	{
		ptemp=(CCalendar*)CA_List.GetAt(i-1);
		if(ptemp->m_Time>p->m_Time)
		{
			CA_List.SetAt(i,(CCalendar*)ptemp);
		}
		else
		{
			CA_List.SetAt(i,(CCalendar*)p);
		    break;
		}
	}
	if(i==0)
     CA_List.SetAt(i,(CCalendar*)p);
}
void  CEatingDlg::Arrial(int i,int j,CCalendar *p)
{
   CString str;//在进度栏里加入事件
   if(m_thinker.tropicStatus[j]==0) //如果筷子是空闲的
   {
	   m_thinker.HaveTrop[i]++;
	   if(m_thinker.HaveTrop[i]==2)
	   {
	      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);
	   }
	   else
	   {  
          int  l;
	      if(p->m_Customer==j)
			  l=(p->m_Customer+4)%5;
		  else
			  l=p->m_Customer;
		  m_thinker.tropicStatus[j]=1;//筷子不再是空闲的
          if(m_thinker.WaitBegin[i]==0)     //如果还没有等待的话在这个时刻开始等待
		      m_thinker.WaitBegin[i]=p->m_Time; 

⌨️ 快捷键说明

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