《操作系统课程设计》指导书.docx

上传人:b****5 文档编号:5170567 上传时间:2022-12-13 格式:DOCX 页数:19 大小:63.22KB
下载 相关 举报
《操作系统课程设计》指导书.docx_第1页
第1页 / 共19页
《操作系统课程设计》指导书.docx_第2页
第2页 / 共19页
《操作系统课程设计》指导书.docx_第3页
第3页 / 共19页
《操作系统课程设计》指导书.docx_第4页
第4页 / 共19页
《操作系统课程设计》指导书.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

《操作系统课程设计》指导书.docx

《《操作系统课程设计》指导书.docx》由会员分享,可在线阅读,更多相关《《操作系统课程设计》指导书.docx(19页珍藏版)》请在冰豆网上搜索。

《操作系统课程设计》指导书.docx

《操作系统课程设计》指导书

《操作系统原理》课程设计参考

2018年12月

课设的目的

操作系统是计算机专业的一门专业课,也是计算机专业考研课程,但操作系统比较抽象,有的同学一学期完了都还很难理解进程、内存管理等一些概念和原理,操作系统课程设计的目的就是通过设计的实验,让同学们真正理解进程的实现,内存管理的机制,达到理解概念,了解实现原理。

同时也进一步巩固程序设计与数据结构的实践技能,实现整个大学阶段实践技能不断线的目的。

课设的故事

一个操作系统采用请求页式管理方式来管理内存。

当一个进程在运行中,随着进程的执行,它会不断的访问内存<代码执行、存取数据),这样就会提出内存访问请求。

操作系统会根据用户进程提出的访存请求,来做地址变换,从而访问到用户进程想要访问的代码或数据。

操作系统进行地址变换的过程中发现用户将要访问的地址所在的虚页还没有进入内存会自动将该虚页从磁盘中装入内存,再进行地址变换。

当然若新的页调入内存之前,该进程所能使用的最大内存块数已经用完的话,操作系统就会从该进程已经在内存的那些页中根据先进先出的原则来淘汰掉一个页,腾出空间给将要正要请求访问的页。

所以操作系统要记录每个进程的每个页面的状态,记录这些调入内存的页面的顺序,还要记录内存中各个块的使用情况。

这些都是操作系统必需动态维护的数据,是操作系统的信息基础。

现假设一个计算机系统有内存mKB,系统的页面大小为1KB,假设操作系统占用内存低端的n个块

所谓“随机+顺序”的内存块分配方式就是用随机数来确定一个起始探测的开始块号,如果其已经被分配,则向下一块探测,如果还是已经分配,则继续下探,直到找到可用块,如果已经到内存的尾部则回到操作系统分界处继续下探。

操作系统采用固定可用块数的方式给每个进程使用和分配内存块,并且规定最大内存块数为x,当某个进程已经用完了它的最大内存块数后就要淘汰页面了。

模拟计算机系统允许最大并发进程数为y,假设目前进程数已经达到最大进程数。

为了模拟某个进程,其所需的页面数z由随机数产生(m/10,页面推进的过程采用随机数方式给出访存地址a,逻辑地址a应该在0到zKB-1之间,操作系统负责对逻辑地址a进行地址变换,并维护整个系统内存管理的所有数据结构,保证进程的顺利推进,使内存得以共享,实现虚拟存储器的功能。

要求课设实现的系统能够配置上述参数,并按照配置参数的规模来系统的模拟系统的运行过程。

希望可以可视化的展示系统内部的变化。

课设的方案

1构造页面、进程、内存管理所需的数据结构,动态管理系统中的有关信息。

#defineMAX_MEMORY_FRAME_COUNT200//最大允许设置的内存大小<以块为单位)

classCPage:

publicCObject//逻辑页的信息

{

DECLARE_DYNCREATE(CPage>

public:

CPage(>。

boolbInMemoryFlag。

//该页是否在内存

intnFrameNo。

//内存的快号

intnDiskRelBlockNo。

//磁盘的相对块号<可以随机给定)

intnNextPageNo。

//下一调进内存页的页号

boolbModifiedFlag。

//修改位<可以随机给定)

//...

}。

classCProcess:

publicCObject//进程的信息

{

DECLARE_DYNCREATE(CProcess>

public:

CProcess(>。

voidInitProcessParameter(intno,intpagetotal,intruntime>。

intGetOneLogicalAddress(>。

//得到下一要访问的页的页号

voidAddressMapping(intLogicalAddress>。

intnPID。

//进程标识符

charszProcessName[20]。

//进程名

intnControlNo。

intnStatus。

intnPageCountLogicalSpace。

//逻辑地址空间的页数

intnPageCountInMemory。

//调入内存的页数

intnRunTime。

//运行时间<运行步数)

intnPageNoHead。

//调入内存的首页

intnPageNoTail。

//调入内存的末页

//其他信息,如就绪或阻塞队列指针----自己可以根据自己的能力与爱好进一步完善下去

CPage*PageTable。

}。

intMaxFrameCount。

intGetOneRandDiskNo(>//随机产生一个虚页在磁盘的相对块号

{

returnrand(>%(1024*1024>。

}

CPage:

:

CPage(>

{

bInMemoryFlag=0。

//该页是否在内存

nFrameNo=0。

//内存的快号

nDiskRelBlockNo=GetOneRandDiskNo(>。

//磁盘的相对块号<可以随机给定)

nNextPageNo=0。

//下一调进内存页的页号

bModifiedFlag=0。

//修改位<可以随机给定)

}

IMPLEMENT_DYNCREATE(CPage,CObject>

CProcess:

:

CProcess(>

{

nPID=(int>this。

nPageCountInMemory=0。

nStatus=0。

nPageNoHead=0。

nPageNoTail=0。

PageTable=NULL。

}

voidCProcess:

:

InitProcessParameter(intno,intpagetotal,intruntime>

{

sprintf(szProcessName,"ProcName%1d",no>。

//进程名

nControlNo=no。

nPageCountLogicalSpace=pagetotal。

//逻辑地址空间的页数

nRunTime=runtime。

//运行时间<运行步数)

PageTable=newCPage[nPageCountLogicalSpace]。

//根据实际需要创建页表

}

intCProcess:

:

GetOneLogicalAddress(>//得到下一要访问的页的页号

{

intran_num。

ran_num=rand(>%nPageCountLogicalSpace。

returnran_num。

}

voidCProcess:

:

AddressMapping(intLogicalAddress>

{

intnIndexIn=LogicalAddress。

//正在访问到的页的页号

intnIndexOut。

intnFrameNoReused。

//

if(PageTable[nIndexIn].bInMemoryFlag==0>//未装入内存

{

if(nPageCountInMemory//本进程使用的内存块数未达最大块数

{

PageTable[nIndexIn].nFrameNo=COsExamDlg:

:

AllocateMemoryFrame(nControlNo>。

//请求分配一块

PageTable[nIndexIn].bInMemoryFlag=true。

//维护链表

if(nPageCountInMemory==0>//第一个页面装入内存

{

PageTable[nIndexIn].nNextPageNo=-1。

this->nPageNoHead=nIndexIn。

this->nPageNoTail=nIndexIn。

}

else

{

PageTable[nIndexIn].nNextPageNo=-1。

//刚装入的页面的Next指针设为-1<终点)

PageTable[this->nPageNoTail].nNextPageNo=nIndexIn。

this->nPageNoTail=nIndexIn。

}

nPageCountInMemory++。

}

else//本进程使用的内存块数已达最大块数

{

//淘汰一页

nIndexOut=this->nPageNoHead。

nFrameNoReused=PageTable[nIndexOut].nFrameNo。

//暂存被重用的内存块的块号

this->nPageNoHead=PageTable[nIndexOut].nNextPageNo。

//把首页设到原来的第二个顺序页

PageTable[nIndexOut].nFrameNo=-1。

//原来的页设成不在内存

PageTable[nIndexOut].bInMemoryFlag=false。

PageTable[nIndexIn].nFrameNo=nFrameNoReused。

//访问页装入腾出的块

PageTable[nIndexIn].bInMemoryFlag=true。

//设为“已装入”

PageTable[nIndexIn].nNextPageNo=-1。

//刚访问的页面的Next指针设为-1<终点)

PageTable[this->nPageNoTail].nNextPageNo=nIndexIn。

//附加到链表

this->nPageNoTail=nIndexIn。

//设置为新的“链尾”

//

}

//设置内存映像的显示串

//。

}

else//访问地址对应的页已在内存

{

//直接访问

}

}

2设计使用上述数据结构来实现请求分页模拟系统

下面的例子是用VC的对话框应用程序来实现的测试或应用系统模型。

进程的推进由windows的线程来模拟的,这里进程的内容是由随机数产生运行轨迹。

intCOsExamDlg:

:

m_sMemoryFrameCount=120。

intCOsExamDlg:

:

m_sOsFrameCount=40。

boolbMemoryBitmap[MAX_MEMORY_FRAME_COUNT]。

//内存空间管理的位示图

CStringcsMemoryBitmap。

//用于显示内存使用情况的字符串

intGetOneLogicalAddress(>

{

return0。

}

UINTBarryProcessThreadProc(LPVOIDpParam>//模拟进程的线程函数

{

CProcess*pProcess=(CProcess*>pParam。

if(pProcess==NULL||!

pProcess->IsKindOf(RUNTIME_CLASS(CProcess>>>

return1。

//如果pObject无效,则返回1

//添加执行代码

CStringcsOutputInfo=""。

inti。

intLA。

for(i=0。

inRunTime。

i++>//执行每个操作步

{

//随机产生一个访问地址

LA=GetOneLogicalAddress(>。

//地址变换--改变数据结构,改变用户界面

pProcess->AddressMapping(LA>。

csOutputInfo+="M"。

//构造显示页表信息的串

 

CWnd*pMainWnd。

pMainWnd=AfxGetMainWnd(>。

switch(pProcess->nControlNo>

{

case0:

pMainWnd->GetDlgItem(IDC_STATIC_PROCESS0>->SetWindowText(csOutputInfo>。

break。

case1:

pMainWnd->GetDlgItem(IDC_STATIC_PROCESS1>->SetWindowText(csOutputInfo>。

break。

case2:

pMainWnd->GetDlgItem(IDC_STATIC_PROCESS2>->SetWindowText(csOutputInfo>。

break。

case3:

pMainWnd->GetDlgItem(IDC_STATIC_PROCESS3>->SetWindowText(csOutputInfo>。

break。

}

//延时

Sleep(1000>。

}

return0。

//threadcompletedsuccessfully!

 

}

 

CProcess*ProcessPool。

 

voidCOsExamDlg:

:

OsInitialization(>

{

inti。

csMemoryBitmap=""。

for(i=0。

i

i++>

{

bMemoryBitmap[i]=false。

csMemoryBitmap+=""。

}

}

intCOsExamDlg:

:

AllocateMemoryFrame(intnProcessNo>

{

intnFrameNoStart。

nFrameNoStart=m_sOsFrameCount+rand(>%(m_sMemoryFrameCount-m_sOsFrameCount>。

while(bMemoryBitmap[nFrameNoStart]==true>

{

nFrameNoStart=nFrameNoStart+1。

if(nFrameNoStart==m_sMemoryFrameCount>

nFrameNoStart=m_sOsFrameCount。

}

returnnFrameNoStart。

}

 

COsExamDlg:

:

COsExamDlg(CWnd*pParent/*=NULL*/>

:

CDialog(COsExamDlg:

:

IDD,pParent>

{

//{{AFX_DATA_INIT(COsExamDlg>

m_nProcessCount=0。

m_nMemoryFrameCount=0。

m_nOsFrameCount=0。

m_nMaxFrameForOneProcess=0。

//}}AFX_DATA_INIT

//NotethatLoadIcondoesnotrequireasubsequentDestroyIconinWin32

m_hIcon=AfxGetApp(>->LoadIcon(IDR_MAINFRAME>。

 

m_nProcessCount=3。

m_nMaxFrameForOneProcess=16。

m_nMemoryFrameCount=64。

m_nOsFrameCount=16。

}

voidCOsExamDlg:

:

DoDataExchange(CDataExchange*pDX>

{

CDialog:

:

DoDataExchange(pDX>。

//{{AFX_DATA_MAP(COsExamDlg>

DDX_Text(pDX,IDC_EDIT_PROCESS_COUNT,m_nProcessCount>。

DDX_Text(pDX,IDC_EDIT_MEMORY_FRAME_COUNT,m_nMemoryFrameCount>。

DDV_MinMaxInt(pDX,m_nMemoryFrameCount,64,128>。

DDX_Text(pDX,IDC_EDIT_OS_FRAME_COUNT,m_nOsFrameCount>。

DDV_MinMaxInt(pDX,m_nOsFrameCount,16,32>。

DDX_Text(pDX,IDC_EDIT_MAX_FRAME_COUNT_PER_PROCESS,m_nMaxFrameForOneProcess>。

DDV_MinMaxInt(pDX,m_nMaxFrameForOneProcess,4,16>。

//}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(COsExamDlg,CDialog>

//{{AFX_MSG_MAP(COsExamDlg>

ON_WM_SYSCOMMAND(>

ON_WM_PAINT(>

ON_WM_QUERYDRAGICON(>

ON_BN_CLICKED(IDC_BUTTON_ACCEPT,OnButtonAccept>

ON_BN_CLICKED(IDC_BUTTON_SIMU,OnButtonSimu>

//}}AFX_MSG_MAP

END_MESSAGE_MAP(>

/////////////////////////////////////////////////////////////////////////////

//COsExamDlgmessagehandlers

BOOLCOsExamDlg:

:

OnInitDialog(>

{

CDialog:

:

OnInitDialog(>。

//Add"About..."menuitemtosystemmenu.

//IDM_ABOUTBOXmustbeinthesystemcommandrange.

ASSERT((IDM_ABOUTBOX&0xFFF0>==IDM_ABOUTBOX>。

ASSERT(IDM_ABOUTBOX<0xF000>。

CMenu*pSysMenu=GetSystemMenu(FALSE>。

if(pSysMenu!

=NULL>

{

CStringstrAboutMenu。

strAboutMenu.LoadString(IDS_ABOUTBOX>。

if(!

strAboutMenu.IsEmpty(>>

{

pSysMenu->AppendMenu(MF_SEPARATOR>。

pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu>。

}

}

//Settheiconforthisdialog.Theframeworkdoesthisautomatically

//whentheapplication'smainwindowisnotadialog

SetIcon(m_hIcon,TRUE>。

//Setbigicon

SetIcon(m_hIcon,FALSE>。

//Setsmallicon

//TODO:

Addextrainitializationhere

 

GetDlgItem(IDC_EDIT_PAGE_COUNT0>->SetWindowText("12">。

 

GetDlgItem(IDC_EDIT_PAGE_COUNT0>->SetWindowText("12">。

GetDlgItem(IDC_EDIT_RUN_TIME0>->SetWindowText("12">。

GetDlgItem(IDC_EDIT_PAGE_COUNT1>->SetWindowText("8">。

GetDlgItem(IDC_EDIT_RUN_TIME1>->SetWindowText("12">。

 

GetDlgItem(IDC_EDIT_PAGE_COUNT2>->SetWindowText("16">。

GetDlgItem(IDC_EDIT_RUN_TIME2>->SetWindowText("12">。

GetDlgItem(IDC_EDIT_PAGE_COUNT3>->SetWindowText("9">。

GetDlgItem(IDC_EDIT_RUN_TIME3>->SetWindowText("12">。

 

srand(time(0>>。

 

returnTRUE。

//returnTRUEunlessyousetthefocustoacontrol

}

voidCOsExamDlg:

:

OnSysCommand(UINTnID,LPARAMlParam>

{

if((nID&0xFFF0>==IDM_ABOUTBOX>

{

CAboutDlgdlgAbout。

dlgAbout.DoModal(>。

}

else

{

CDialog:

:

OnSysCommand(nID,lParam>。

}

}

//Ifyouaddaminimizebuttontoyourdialog,youwillneedthecodebelow

//todrawtheicon.ForMFCapplicationsusingthedocument/viewmodel,

//thisisautomaticallydoneforyoubytheframework.

voidCOsExamDlg:

:

OnPaint(>

{

if(IsIconic(>>

{

CPaintDCdc(this>。

//devicecontextforpainting

SendMessage(WM_ICONERASEBKGND,(WPARAM>dc.GetSafeHdc(>,0>。

//Centericoninclientrectangle

intcxIcon=GetSystemMetrics(SM_CXICON>。

intcyIcon=GetSystemMetrics(SM_CYICON>。

CRectrect。

GetClientRect(&rect>。

intx=(rect.Width(>-cxIcon+1>/2。

inty=(rect.Height(>-cyIcon+1>/2。

//Drawtheicon

dc.DrawIcon(x,y,m_hIcon>。

}

else

{

CDialog:

:

OnPaint(>。

}

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 考试认证 > 司法考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1