📄 eatingdlg.cpp
字号:
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 + -