实践 哲学家进餐问题.docx
《实践 哲学家进餐问题.docx》由会员分享,可在线阅读,更多相关《实践 哲学家进餐问题.docx(12页珍藏版)》请在冰点文库上搜索。
![实践 哲学家进餐问题.docx](https://file1.bingdoc.com/fileroot1/2023-6/25/aaecedaf-a57a-407d-b2f0-f6b0e17342a5/aaecedaf-a57a-407d-b2f0-f6b0e17342a51.gif)
实践哲学家进餐问题
实践15哲学家进餐问题
1.实践内容说明
(1)在函数中使用图形方式显示哲学家进餐问题,每个哲学家使用一个线程控制,随机进行进餐或者思考,使用互斥量与事件进行同步与互斥控制。
2.程序性质
(1)Windows与控制台混合应用程序
(2)多线程
3.运行环境设置
(1)建立项目在VisualC++6、0开发环境,单击New菜单,弹出New对话框;在New对话框中选择Project标签切换至Project标签页;在Project标签页得项目列表中选择Win32Application选项,Location输入框输入项目所在得路径,或者单击输入框右侧得按钮,在弹出得ChooseDirectory对话框中选择项目所在得磁盘分区与所在得目录;在Project标签页得Projectname输入框中输入项目名称;Project标签页中得其她选项保持默认选择(单选框Createnewworkspace前有黑点,Platforms选项框中Win32前打勾),完成设置界面如图10所示。
图10设置项目为Windows应用
完成设置后单击OK,New对话框关闭,弹出Win32ConsoleApplication–Step1of1对话框。
在Win32ConsoleApplication–Step1of1对话框中选择Anemptyproject单选项。
Win32ConsoleApplication–Step1of1对话框如图11所示。
图11说明刚建立得项目为空项目
完成Win32ConsoleApplication–Step1of1对话框后单击Finish按钮,Win32ConsoleApplication–Step1of1对话框关闭,弹出NewProjectInformation对话框。
NewProjectInformation对话框中显示了当前建立项目得一些信息。
NewProjectInformation对话框如图12所示。
图12显示新项目信息
单击NewProjectInformation对话框中得OK按钮,关闭NewProjectInformation对话框,项目建立步骤完成。
(2)建立文件单击File菜单中得New菜单项,弹出New对话框。
在New对话框中单击Files标签,切换至Files标签页;在Files标签页得文件列表中选择C++SourceFile选项,在File输入框中输入文件名。
New对话框设置如图13所示。
图13在新建得项目中建立一个C文件
完成New对话框设置后,单击OK按钮关闭New对话框,在项目中创建文件步骤完成。
(3)输入文件在创建得文件窗口中输入要调试运行得操作系统源文件。
(4)修改编译设置单击Project菜单中得Settings菜单项,弹出ProjectSettings对话框。
在ProjectSettings对话框中单击C/C++标签,切换至C/C++标签页;在C/C++标签页中得Category下拉列表选择框中选择CodeGeneration选择项;在Userun-timelibrary下拉列表选择框中选择DebugMultithreadedDLL选项。
设置界面如图14所示。
图14设置成多线程环境完成设置后单击OK按钮关闭ProjectSettings对话框。
(5)编译运行单击Build菜单中得RebuildAll菜单项编译项目,或者单击工具栏中BuildMinibar工具
栏得Build工具按钮编译项目。
BuildMinibar工具栏形状为,Build
工具按钮对应得图标为,对应得快捷键就是F7。
4实现程序
#include
#include
#include
#include
#defineDEGRESS_TO_RADIAN(x)(x)*3、14/180
typedefstruct
{
HWNDhWnd;//窗口句柄
intchopXY[8];//
intId;//哲学家得编号
intisEating;
}PARAM;
#definePHIL_NUM5//哲学家数目,可改变为其她数目
#defineSTART_POINT150
#defineDESK_DIAMETER200//圆桌直径
#definePHIL_DIAMETER30//哲学家圆圈直径
#defineCHOP_LENGHT50//筷子长度
#defineTIME10000//持续时间长度
intchopSticks[PHIL_NUM];//筷子得初态
intFinished[PHIL_NUM];//用餐就是否完成
HANDLEhMutex;//互斥量
HANDLEhEvent;//事件
unsignedint__stdcallDineMany(LPVOIDpParam);
intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPreInstance,LPSTRpszCmdLine,intnCmdShow);
LRESULTCALLBACKWindowProc(HWNDhWnd,UINTuMsgId,WPARAMwParam,LPARAMlParam);
intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPreInstance,LPSTRpszCmdLine,intnCmdShow)
{
staticcharszAppName[]="哲学家进餐";
HWNDhWnd;
MSGmsg;
WNDCLASSwndClass;
wndClass、style=CS_VREDRAW|CS_HREDRAW;
wndClass、lpfnWndProc=WindowProc;
wndClass、cbClsExtra=0;
wndClass、cbWndExtra=0;
wndClass、hInstance=hInstance;
wndClass、hIcon=LoadIcon(NULL,IDI_QUESTION);
wndClass、hCursor=LoadCursor(NULL,IDC_ARROW);
wndClass、hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wndClass、lpszMenuName=NULL;wndClass、lpszClassName=szAppName;
if(0==RegisterClass(&wndClass))
return0;
hWnd=CreateWindow(szAppName,szAppName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
if(0==hWnd)
return0;
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
returnmsg、wParam;
}
LRESULTCALLBACKWindowProc(HWNDhWnd,UINTuMsgId,WPARAMwParam,LPARAMlParam)
{
HDChDC;
PAINTSTRUCTpaintStruct;
HANDLEhThread[PHIL_NUM];
intleft,right;
staticintchopStartX[PHIL_NUM],chopStartY[PHIL_NUM];//筷子得起始坐标
staticintchopEndX[PHIL_NUM],chopEndY[PHIL_NUM];//筷子得结束坐标
staticintphilX[PHIL_NUM],philY[PHIL_NUM];//哲学家得位置
staticPARAMpParam[PHIL_NUM];
HPENhPenWhite,hOldPen;
inti;
switch(uMsgId)
{
caseWM_CREATE:
hMutex=CreateMutex(NULL,FALSE,NULL);//创建互斥量
hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);//创建事件
for(i=0;i{
chopStartX[i]=(int)((START_POINT)+DESK_DIAMETER/2+DESK_DIAMETER/4*sin(DEGRESS_TO_RADIAN(90+(360、0/PHIL_NUM)*i)));
chopStartY[i]=(int)((START_POINT)+DESK_DIAMETER/2+DESK_DIAMETER/4*cos(DEGRESS_TO_RADIAN(90+(360、0/PHIL_NUM)*i)));
chopEndX[i]=(int)((START_POINT)+DESK_DIAMETER/2+DESK_DIAMETER/2*sin(DEGRESS_TO_RADIAN(90+(360、0/PHIL_NUM)*i)));
chopEndY[i]=(int)((START_POINT)+DESK_DIAMETER/2+DESK_DIAMETER/2*cos(DEGRESS_TO_RADIAN(90+(360、0/PHIL_NUM)*i)));
philX[i]=(int)((START_POINT)+DESK_DIAMETER/2+(DESK_DIAMETER/2+PHIL_DIAMETER)*cos(DEGRESS_TO_RADIAN(-(360、0/(PHIL_NUM*2))-(360、0/PHIL_NUM)*i))-PHIL_DIAMETER/2);
philY[i]=(int)((START_POINT)+DESK_DIAMETER/2+(DESK_DIAMETER/2+PHIL_DIAMETER)*sin(DEGRESS_TO_RADIAN(-(360、0/(PHIL_NUM*2))-(360、0/PHIL_NUM)*i))-PHIL_DIAMETER/2);
chopSticks[i]=0;
Finished[i]=1;
}
break;//绘图消息
caseWM_PAINT:
hDC=BeginPaint(hWnd,&paintStruct);//获得视图设备环境
{
Ellipse(hDC,START_POINT,START_POINT,START_POINT+DESK_DIAMETER,START_POINT+DESK_DIAMETER);//画圆桌
for(i=0;i{
MoveToEx(hDC,chopStartX[i],chopStartY[i],NULL);
LineTo(hDC,chopEndX[i],chopEndY[i]);
}
for(i=0;i{
Ellipse(hDC,philX[i],philY[i],philX[i]+PHIL_DIAMETER,philY[i]+PHIL_DIAMETER);
}
for(i=0;i{
if(pParam[i]、isEating==1)
{
MoveToEx(hDC,philX[i]+PHIL_DIAMETER/2,philY[i]+PHIL_DIAMETER/2,NULL);
LineTo(hDC,pParam[i]、chopXY[2],pParam[i]、chopXY[3]);
MoveToEx(hDC,philX[i]+PHIL_DIAMETER/2,philY[i]+PHIL_DIAMETER/2,NULL);
LineTo(hDC,pParam[i]、chopXY[6],pParam[i]、chopXY[7]);
}
else
{
hPenWhite=CreatePen(PS_SOLID,3,RGB(255,255,255));
hOldPen=(structHPEN__*)SelectObject(hDC,hPenWhite);
MoveToEx(hDC,philX[i]+PHIL_DIAMETER/2,philY[i]+PHIL_DIAMETER/2,NULL);
LineTo(hDC,pParam[i]、chopXY[2],pParam[i]、chopXY[3]);
MoveToEx(hDC,philX[i]+PHIL_DIAMETER/2,philY[i]+PHIL_DIAMETER/2,NULL);
LineTo(hDC,pParam[i]、chopXY[6],pParam[i]、chopXY[7]);
SelectObject(hDC,hOldPen);
DeleteObject(hPenWhite);
}
}
TextOut(hDC,20,20,"presss",7);
}
EndPaint(hWnd,&paintStruct);//释放视图设备环境
break;
caseWM_CHAR:
if(wParam=='s'||wParam=='S')
{
for(i=0;ichopSticks[i]=FALSE;
ResetEvent(hEvent);//事件没信号
for(i=0;i{
pParam[i]、Id=i;
pParam[i]、hWnd=hWnd;
left=i;
right=(i+1)%PHIL_NUM;
pParam[i]、chopXY[0]=chopStartX[left];//左手筷子起始X坐标
pParam[i]、chopXY[1]=chopStartY[left];//左手筷子起始Y坐标
pParam[i]、chopXY[2]=chopEndX[left];//左手筷子结束X坐标
pParam[i]、chopXY[3]=chopEndY[left];//左手筷子结束Y坐标
pParam[i]、chopXY[4]=chopStartX[right];//右手筷子起始X坐标
pParam[i]、chopXY[5]=chopStartY[right];//右手筷子起始Y坐标
pParam[i]、chopXY[6]=chopEndX[right];//右手筷子结束X坐标
pParam[i]、chopXY[7]=chopEndY[right];//右手筷子结束Y坐标
pParam[i]、isEating=0;
hThread[i]=(HANDLE)_beginthreadex(NULL,0,DineMany,&pParam[i],0,NULL);
}
InvalidateRect(hWnd,NULL,FALSE);SetEvent(hEvent);//事件有信号
}
break;
caseWM_CLOSE:
for(i=0;iDestroyWindow(hWnd);
break;
caseWM_DESTROY:
PostQuitMessage(0);
break;
default:
returnDefWindowProc(hWnd,uMsgId,wParam,lParam);
}return0;
}
unsignedint__stdcallDineMany(LPVOIDpParam)
{
PARAM*m_pParam=(PARAM*)pParam;
intleft,right;
intTimeDelay=TIME,SleepTime;
BOOLcanDine=FALSE;
WaitForSingleObject(hEvent,INFINITE);
left=m_pParam->Id;
right=(m_pParam->Id+1)%PHIL_NUM;
while(TimeDelay>0)
{
WaitForSingleObject(hMutex,INFINITE);
if(FALSE==chopSticks[left]&&FALSE==chopSticks[right])
{
chopSticks[left]=TRUE;
chopSticks[right]=TRUE;
canDine=TRUE;
}
ReleaseMutex(hMutex);
if(TRUE==canDine)
{
m_pParam->isEating=1;
InvalidateRect(m_pParam->hWnd,NULL,FALSE);
srand((unsigned)time(NULL));
SleepTime=((rand()%250+250)-(rand()%250-250))/2;
Sleep(SleepTime);
TimeDelay=TimeDelay-SleepTime;
WaitForSingleObject(hMutex,INFINITE);
chopSticks[left]=FALSE;
chopSticks[right]=FALSE;
ReleaseMutex(hMutex);
canDine=FALSE;
m_pParam->isEating=0;
SetEvent(hEvent);
}
if(FALSE==canDine)
{
srand((unsigned)time(NULL));
SleepTime=((rand()%500+500)-(rand()%500-500))/2;
Sleep(SleepTime);
TimeDelay=TimeDelay-SleepTime;
}
}
Finished[m_pParam->Id]=TRUE;
return0L;
}
5实验结果