操作系统实验报告.docx
- 文档编号:9330791
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:17
- 大小:677.63KB
操作系统实验报告.docx
《操作系统实验报告.docx》由会员分享,可在线阅读,更多相关《操作系统实验报告.docx(17页珍藏版)》请在冰豆网上搜索。
操作系统实验报告
操作系统实验报告
实验名称:
哲学家就餐问题
班级:
通信1202班
学号:
U201213584
姓名:
越
指导老师:
许毅平
一、实验目的
1. 熟练使用VC++6.0编译环境,调试并正确运行程序,更加熟练地利用c语言解决问题
2.了解哲学家就餐的基本原理,掌握死锁的必要条件。
3.理解源程序中产生和防止的算法,及相关窗口操作。
二、实验原理
1.问题描述:
有五个哲学家围坐在一圆桌旁,桌中央有一盘通心粉,每人面前有一只空盘子,每两人
之间放一只筷子每个哲学家的行为是思考,感到饥饿,然后吃通心粉.为了吃通心粉,每
个哲学家必须拿到两只筷子,并且每个人只能直接从自己的左边或右边去取筷子。
2.分析问题:
假如所有的哲学家都同时拿起左侧筷子,看到右侧筷子不可用,又都放下左侧筷子,等一会儿,又同时拿起左侧筷子,如此这般,永远重复。
对于这种情况,即所有的程序都在无限期地运行,但是都无法取得任何进展,即出现饥饿,所有哲学家都吃不上饭。
规定在拿到左侧的筷子后,先检查右面的筷子是否可用。
如果不可用,则先放下左侧筷子,等一段时间再重复整个过程。
分析:
当出现以下情形,在某一个瞬间,所有的哲学家都同时启动这个算法,拿起左侧的筷子,而看到右侧筷子不可用,又都放下左侧筷子,等一会儿,又同时拿起左侧筷子……如此这样永远重复下去。
对于这种情况,所有的程序都在运行,但却无法取得进展,即出现饥饿,所有的哲学家都吃不上饭。
解决死锁问题:
为了避免死锁,把哲学家分为三种状态,思考,饥饿,进食,并且一次拿到两只筷子,否则不拿.。
仅当一个哲学家左右两边筷子都可用时,才允许他拿筷子。
这样要么一次占有两只筷子在吃面,然后释放所有资源;要么不占用资源。
这样就不会导致死锁了。
由以上的分析可以得出以下结论:
(1)、防止死锁发生的分配方式:
仅当一个哲学家左右两边的筷子都可用时,才允许他拿筷子。
这样要么一次占有两只筷子(所有线程需要的资源)进行下一步的吃通心粉,然后释放所有的资源;要么不占用资源,这样就不可能产生死锁了。
(2)、产生死锁的分配方式:
当筷子(资源)可用时,先分配左边的筷子,等待一会后再分配右边的筷子,由于这个过程中,左边的筷子一直没有释放,就有可能产生死锁了。
三、实验过程
实验的伪代码如下所示:
1.不发生死锁的方式(要么一下占用两支筷子,要么不占用)
varmutexleftchopstick,mutexrightchopstick;
beging:
resting;
waiting;
p(mutexleftchopstick);
p(mutexrightchopstick);
GetResource(leftchopstick,rightchopstick);
eating;
v(mutexleftchopstick);
v(mutexrightchopstick);
end
2.发生死锁的方式(一旦可以占用筷子,就马上占用)
varmutexleftchopstick,mutexrightchopstick;
beging:
resting;
waiting;
p(mutexleftchopstick);
GetResource(leftchopstick);
p(mutexrightchopstick);
GetResource(rightchopstick);
eating;
v(mutexleftchopstick);
v(mutexrightchopstick);
end
与之前分析的一样,当两只筷子都没被占用时才去获取筷子,这样就打破了死锁的必要条件,即不发生死锁;而当有筷子即占用,看似效率很高,但因为资源有限,且不可抢占,很容易发生死锁。
以下即为该实验的完整源代码:
#defineWIN32_LEAN_AND_MEAN
#include
#include
#include
#include
#include
#include
#include"dining.h"
HINSTANCEhInst;//ApplicationInstanceHandle
HWNDhWndMain;//MainWindowHandle
HBITMAPhbmpOffscreen;
LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);
voidRenderOffscreen(HDChDestDC);
BOOLbWaitMultiple;
BOOLbFastFood;
externintgDinerState[];
externintgChopstickState[];
externHANDLEgchopStick[PHILOSOPHERS];//1chopstickbetweeneachphilopherandhisneighbor
/********************************************************************/
/*ROUTINE:
WndProc*/
/**/
/*PURPOSE:
Processesmessages*/
/********************************************************************/
LRESULTCALLBACKWndProc(HWNDhWnd,UINTmessage,
WPARAMwParam,LPARAMlParam)
{
PAINTSTRUCTps;
HDChdc;
switch(message)
{
caseWM_COMMAND:
switch(wParam)
{
caseCM_EXIT:
PostMessage(hWndMain,WM_CLOSE,0,0L);
break;
}
break;
caseWM_FORCE_REPAINT:
{
MSGmsg;
InvalidateRect(hWndMain,NULL,TRUE);
while(PeekMessage(&msg,hWndMain,WM_FORCE_REPAINT,WM_FORCE_REPAINT,TRUE))
;
}
break;
caseWM_PAINT:
hdc=BeginPaint(hWndMain,&ps);
RenderOffscreen(hdc);
EndPaint(hWndMain,&ps);
break;
caseWM_CLOSE:
returnDefWindowProc(hWndMain,message,wParam,lParam);
caseWM_DESTROY:
PostQuitMessage(0);
break;
default:
returnDefWindowProc(hWnd,message,wParam,lParam);
}
return(0);
}
BOOLCreateOffscreen()
{
HWNDhwndScreen=GetDesktopWindow();
HDChdc=GetDC(hwndScreen);
intnWidth=GetSystemMetrics(SM_CXSCREEN);
intnHeight=GetSystemMetrics(SM_CYSCREEN);
hbmpOffscreen=CreateCompatibleBitmap(hdc,nWidth,nHeight);
ReleaseDC(hwndScreen,hdc);
if(!
hbmpOffscreen)
returnFALSE;
else
returnTRUE;
}
voidRenderOffscreen(HDChDestDC)
{
HDChdc=hDestDC;//CreateCompatibleDC(hWndMain);
interr=GetLastError();
HBITMAPhOldBitmap=SelectObject(hdc,hbmpOffscreen);
RECTrect;
HPENhPen;
doubledx,dy,px,py,AngRad,dDeltaAng;
intpos,p1;
longCenterX,CenterY;
hPen=SelectObject(hdc,CreatePen(PS_SOLID,3,0L));
GetClientRect(hWndMain,&rect);
/*Drawthetable*/
CenterX=(rect.right-rect.left)/2;
CenterY=(rect.bottom-rect.top)/2;
Ellipse(hdc,CenterX-100,CenterY-100,CenterX+100,CenterY+100);
/*Drawthechopsticks*/
dDeltaAng=360/PHILOSOPHERS;//筷子间的角度差
for(pos=0;pos { /*Drawthechopsticks*/ AngRad=(pos*dDeltaAng)/57.29577951;//转化为弧度 dx=CenterX+(sin(AngRad)*60); dy=CenterY-(cos(AngRad)*60); MoveToEx(hdc,(int)dx,(int)dy,NULL); dx=CenterX+(sin(AngRad)*85); dy=CenterY-(cos(AngRad)*85); LineTo(hdc,(int)dx,(int)dy); //Drawtheplate AngRad=((pos*dDeltaAng+dDeltaAng/2))/57.29577951;//转化为弧度 dx=CenterX+(sin(AngRad)*72); dy=CenterY-(cos(AngRad)*72); Ellipse(hdc,(int)dx-12,(int)dy-12,(int)dx+12,(int)dy+12); } /*deletetheblackpen*/ DeleteObject(SelectObject(hdc,hPen)); /*Drawthephilosophers*/ for(pos=0;pos { /*selectapenforeachphilosopher*/ switch(gDinerState[pos]) { caseRESTING: hPen=SelectObject(hdc,CreatePen(PS_SOLID,3,RGB(0,255,0))); break; caseWAITING: caseEATING: hPen=SelectObject(hdc,CreatePen(PS_SOLID,3,RGB(255,0,0))); break; default: hPen=SelectObject(hdc,CreatePen(PS_SOLID,3,0L)); } AngRad=((pos*dDeltaAng)+dDeltaAng/2)/57.29577951; px=CenterX+(sin(AngRad)*150); py=CenterY-(cos(AngRad)*150); /*DrawthePhilosopher*/ Ellipse(hdc,(int)px-25,(int)py-25,(int)px+25,(int)py+25); //Drawtheleftarm if(gChopstickState[pos]==pos) { MoveToEx(hdc,(int)px,(int)py,NULL); AngRad=(pos*dDeltaAng)/57.29577951;//转化为弧度 dx=CenterX+(sin(AngRad)*85); dy=CenterY-(cos(AngRad)*85); LineTo(hdc,(int)dx,(int)dy); } //Drawtherightarm p1=pos+1; if(p1==PHILOSOPHERS) p1=0; if(gChopstickState[p1]==pos) { MoveToEx(hdc,(int)px,(int)py,NULL); AngRad=(p1*dDeltaAng)/57.29577951; dx=CenterX+(sin(AngRad)*85); dy=CenterY-(cos(AngRad)*85); LineTo(hdc,(int)dx,(int)dy); } /*Deletethepen*/ DeleteObject(SelectObject(hdc,hPen)); }//forpos BitBlt(hDestDC, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, hdc, rect.left, rect.top, SRCCOPY ); GetLastError(); SelectObject(hdc,hOldBitmap); //DeleteDC(hWndMain,hdc); } /********************************************************************/ /*ROUTINE: InitApplication*/ /**/ /*PURPOSE: Initializetheapplication*/ /********************************************************************/ BOOLInitApplication(HINSTANCEhInstance) { WNDCLASSwc; wc.style=CS_HREDRAW|CS_VREDRAW; wc.lpfnWndProc=WndProc; wc.cbClsExtra=0; wc.cbWndExtra=0; wc.hInstance=hInstance; wc.hIcon=LoadIcon(NULL,IDI_APPLICATION); wc.hCursor=LoadCursor(NULL,IDC_ARROW); wc.hbrBackground=(HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName="din"; wc.lpszClassName="dinWClass"; RegisterClass(&wc); returnTRUE; } /********************************************************************/ /*ROUTINE: InitInstance*/ /**/ /*PURPOSE: Savesinstancehandleandcreatesmainwindow*/ /********************************************************************/ BOOLInitInstance(HINSTANCEhInstance,intnCmdShow) { intret; hInst=hInstance; hWndMain=CreateWindow( "dinWClass", "DiningPhilosopher", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 450, 450, NULL,NULL,hInstance,NULL); if(! hWndMain) returnFALSE; ShowWindow(hWndMain,nCmdShow); UpdateWindow(hWndMain); if(! CreateOffscreen()) PostQuitMessage (1); ret=MessageBox(hWndMain,"你期望使用防死锁运行模式吗? \n\n" "如果选择Yes,程序将正常运行.\n" "如果选择No,程序会进入死锁.\n", "WaitMode",MB_YESNO); if(ret==IDYES) bWaitMultiple=TRUE; else { bWaitMultiple=FALSE; ret=MessageBox(hWndMain,"你期望快速进入死锁吗? \n\n" "如果选择Yes,将更快进入死锁.\n", "WaitMode",MB_YESNO); if(ret==IDYES) bFastFood=TRUE; else bFastFood=FALSE; } //Startthethreads Diner(); returnTRUE; } /********************************************************************/ /*FUNCTION: WinMain*/ /**/ /*PURPOSE: Callsinitializationfunction,processesmessageloop*/ /********************************************************************/ intPASCALWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance, LPSTRlpCmdLine,intnCmdShow) { MSGmsg; inti; if(! hPrevInstance) if(! InitApplication(hInstance)) return(FALSE); if(! InitInstance(hInstance,nCmdShow)) return(FALSE); while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } //Clearthetable for(i=0;i CloseHandle(gchopStick[i]);//关闭互斥体句柄 return(msg.wParam); } 程序运行如下所示 选择yes表示采用的是运行的防止死锁的方式,这样的话整个程序可以一直运行下去,不会产生死锁,如下图所示 在此仅选取以上四个不死锁的状态,其实运行时可以发现,程序可以一直运行下去。 选择no表示运行产生死锁的方式会弹出第二个对话框。 选择res线程时间比较短,很快就可以死锁 选择no线程时间跟选择yes时候的时间差不多,产生死锁的时间稍微长一点,此处就不再截图了。 四、思考题 其他解决死锁的方案: 为资源(这里是餐叉)分配一个偏序或者分级的关系,并约定所有资源都按照这种顺序获取,按相反顺序释放,而且保证不会有两个无关资源同时被同一项工作所需要。 在哲学家就餐问题中,资源(餐叉)按照某种规则编号为1至5,每一个工作单元(哲学家)总是先拿起左右两边编号较低的餐叉,再拿编号较高的。 用完餐叉后,他总是先放下编号较高的餐叉,再放下编号较低的。 在这种情况下,当四位哲学家同时拿起他们手边编号较低的餐叉时,只有编号最高的餐叉留在桌上,从而第五位哲学家就不能使用任何一只餐叉了。 而且,只有一位哲学家能使用最高编号的餐叉,所以他能使用两只餐叉用餐。 当他吃完后,他会先放下编号最高的餐叉,再放下编号较低的餐叉,从而让另一位哲学家拿起后边的这只开始吃东西。 四、实验总结 此次试验的代码比较长,且和以前学的c语言有些不同,特别是图形界面这方面的,在理解好算法后,我还是花了一些时间的去看与算法有关的代码的,有些收获。 而且对哲学家就餐这个经典问题有了更深的了解,这些算法都很好。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)