进程调度操作系统课程设计.docx

上传人:b****5 文档编号:8361659 上传时间:2023-01-30 格式:DOCX 页数:31 大小:649.05KB
下载 相关 举报
进程调度操作系统课程设计.docx_第1页
第1页 / 共31页
进程调度操作系统课程设计.docx_第2页
第2页 / 共31页
进程调度操作系统课程设计.docx_第3页
第3页 / 共31页
进程调度操作系统课程设计.docx_第4页
第4页 / 共31页
进程调度操作系统课程设计.docx_第5页
第5页 / 共31页
点击查看更多>>
下载资源
资源描述

进程调度操作系统课程设计.docx

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

进程调度操作系统课程设计.docx

进程调度操作系统课程设计

 

一.课程概述

1.1.设计构想

程序能够完成以下操作:

1、创建进程。

2、修改进程的优先级、创建时间、服务时间。

3、启动进程算法,先来先服务、时间片轮转、高优先级优先调度。

4、进程运行状态显示。

1.2.需求分析

在多道程序环境下,主存中有着多个进程,其数目往往多于处理机数目,要使这多个进程能够并发地执行,这就要求系统能按某种算法,动态地把处理机分配给就绪队列中的一个进程,使之执行。

分配处理机的任务是由处理机调度程序完成的。

由于处理机是最重要的计算机资源,提高处理机的利用率及改善系统必(吞吐量、响应时间),在很大程度上取决于处理机调度性能的好坏,因而,处理机调度便成为操作系统设计的中心问题之一。

本次实验在vs2010环境下实现先来先服务调度算法,时间片轮转调度算法和高优先权调度算法。

1.3.理论依据

   为了描述和管制进程的运行,系统为每个进程定义了一个数据结构——进程控制块PCB(Process Control Block),PCB中记录了操作系统所需的、用于描述进程的当前情况以及控制进程运行的全部信息,系统总是通过PCB对进程进行控制,亦即,系统是根据进程的PCB而不是任何别的什么而感知进程的存在的,PCB是进程存在的惟一标志。

本次课程设计用结构体ProNode代替PCB的功能。

1.4.课程任务

1、用C语言(或C++)编程实现操作模拟操作系统进程调度子系统的基本功能;运用多种算法实现对进程的模拟调度。

 

2、通过编写程序实现进程或作业先来先服务、按时间片轮转、高优先权,使学生进一步掌握进程调度的概念和算法,加深对处理机分配的理解。

 

3、用MFC实现程序界面。

1.5.功能模块分析:

 

1、进程概念:

进程是被独立分配资源的最小单位。

进程是动态概念,必须程序运行才有进程的产生。

 

2、进程的状态模型:

    

(1)完成:

进程已经完成。

 

(2)就绪:

进程已经准备好,一旦有处理器就可运行。

 

3、处理机调度:

在多道程序设计系统中,内存中有多道程序运行,他们相互争夺处理机这一重要的资源。

处理机调度就是从就绪队列中,按照一定的算法选择一个进程并将处理机分配给它运行,以实现进程并发地执行。

4、进程调度算法的功能:

 

记录系统中所有进程的执行情况、选择占有处理机的进程、进行进程的上下文切换。

5、进程调度的算法:

 

(1)先来先服务算法:

如果早就绪的进程排在就绪队列的前面,迟就绪的进程排在就绪队列的后面,那么先来先服务总是把当前处于就绪队列之首的那个进程调度到运行状态。

 

(2)时间片轮转算法:

固定时间片,每个进程在执行一个时间片后,轮到下一进程

执行,知道所有的进程执行完毕。

处理器同一个时间只能处理一个任务。

处理器在处理多任务的时候,就要看请求的时间顺序,如果时间一致,就要进行预测。

挑到一个任务后,需要若干步骤才能做完,这些步骤中有些需要处理器参与,有些不需要(如磁盘控制器的存储过程)。

不需要处理器处理的时候,这部分时间就要分配给其他的进程。

原来的进程就要处于等待的时间段上。

经过周密分配时间,宏观上就象是多个任务一起运行一样,但微观上是有先后的,就是时间轮换。

(3)优先数算法:

即进程的执行顺序由高优先级到低优先级。

系统或用户按某种原则为进程指定一个优先级来表示该进程所享有的确调度优先权。

该算法核心是确定进程的优先级。

 

二.总体方案设计

2.1程序结构

程序一共添加了4个线程,分别是保存修改线程,先来先服务线程,时间片轮转线程,高优先权优先服务线程。

 

 

图2.1程序结构图

 

三.详细设计

3.1.界面设计

图3.1. 界面设计

3.1.1.进程属性控制

图3.1.1.进程属性控制

3.1.2.进程算法

图3.1.2.进程算法

 

3.1.3.进程运行状态显示

.

图3.1.2.进程算法

3.1.4.设置停顿时间

图3.1.4设置停顿时间

3.1.4.1相关类及其主要函数

classSetTime:

publicCDialogEx

{

DECLARE_DYNAMIC(SetTime)

public:

SetTime(CWnd*pParent=NULL);//标准构造函数

virtual~SetTime();

//对话框数据

enum{IDD=IDD_SETTIME};

protected:

virtualvoidDoDataExchange(CDataExchange*pDX);//DDX/DDV支持

DECLARE_MESSAGE_MAP()

public:

intm_time;

};

SetTime:

:

SetTime(CWnd*pParent/*=NULL*/)

:

CDialogEx(SetTime:

:

IDD,pParent)

m_time(3)

{

}

3.1.5.设置时间片

图3.1.5设置时间片

3.1.5.1相关类及其主要函数

classSeep:

publicCDialogEx

{

DECLARE_DYNAMIC(Seep)

public:

Seep(CWnd*pParent=NULL);//标准构造函数

virtual~Seep();

//对话框数据

enum{IDD=IDD_SLEEP};

protected:

virtualvoidDoDataExchange(CDataExchange*pDX);//DDX/DDV支持

DECLARE_MESSAGE_MAP()

public:

intm_sleep;

};

3.1.6.菜单

图3.1.5设置时间片

 

3.1.6.1保存输入框修改

voidCprogressDlg:

:

OnSave()

{

CWinThread*MainStartThread;

LPVOIDlmainparam=(LPVOID)this;//把this指针作为参数传进去

MainStartThread=:

:

AfxBeginThread(

ThreadFuncSave,

(LPVOID)lmainparam,

THREAD_PRIORITY_NORMAL,

0,

0,

NULL

);

}

3.1.6.2设置时间片大小

voidCprogressDlg:

:

OnSetrr()

{

SetTimedlg;

if(dlg.DoModal()==IDOK)

{

m_timerr=dlg.m_time;

}

}

3.1.6.3设置停顿时间

voidCprogressDlg:

:

OnSeeptime()

{

Seepdlg;

if(dlg.DoModal()==IDOK)

{

m_sleep=dlg.m_sleep;

}

}

3.2.先来先服务调度

3.2.1算法思想 

先来先服务调度算法的思想是按照进程进入就绪队列的先后顺序调度并分配处理机执行。

先来先服务调度算法是一种不可抢占的算法,先进入就绪队列的进程,先被处理机运行。

一旦一个进程占有了处理机,它就一直运行下去,直到该进程完成工作或者因为等待某事件而不能继续运行时才释放处理机。

3.2.2.算法代码

voidCprogressDlg:

:

FCFS(void)

{

inti=0,j;

CreateTimeArray();//创建时间数组

while(!

IsFinish())

{

//找出已创建的进程

while(!

IsCreate(m_time[i])||m_pronode[m_time[i]].prostate==FINISH)

{

++i;

if(i==5)

{

m_systime+=1;

i=0;

ProShow();//更新进程运行状态

}

}

//进程服务

for(j=0;j

{

m_systime+=1;

m_pronode[m_time[i]].finishpart+=1;

ProShow();//更新进程运行状态

}

m_pronode[m_time[i]].prostate=FINISH;

}

}

3.2.3.算法流程图

 

图3.2.先来先服务调度流程图

 

3.3.时间片轮转调度

3.3.1.算法思想 

 所有就绪进程按先来先服务的原则排成一个队列,将新来的进程加到就绪对列的末尾,每当执行进程调度时,总是把处理机分配给队首的进程,各进程占用CPU的时间片相同。

也就是说CPU的处理时间划分成一个个相同的时间片,就绪队列的所有进程轮流运行一个时间片。

当一个时间片结束时,如果运行进程用完它的时间片后还未完成,就强迫运行进程让出CPU,就把它送回到就绪队列的末尾,等待下一次调度。

同时,进程调度又去选择就绪队列中的队首进程,分配给它一时间片,以投入运行。

直至所有的进程运行完毕。

3.3.2.算法流程图

 

 

图3.3.时间片轮转调度流程图

 

3.3.3.程序代码

voidCprogressDlg:

:

RR(void)

{

inti=0;

CreateTimeArray();//创建时间数组

while(!

IsFinish())

{

//找出已创建的进程

while(!

IsCreate(m_time[i])||m_pronode[m_time[i]].prostate==FINISH)

{

++i;

if(i>=5)

{

m_systime+=1;

i=0;

ProShow();//更新进程运行状态

}

}

//进程服务

for(intr=0;r

{

if(m_pronode[m_time[i]].finishpart==m_pronode[m_time[i]].servetime)

m_pronode[m_time[i]].prostate=FINISH;

else

{

m_systime+=1;

m_pronode[m_time[i]].finishpart+=1;

ProShow();//更新进程运行状态

}

}

++i;

if(i>=5)

i=0;

}

}

3.4.优先级调度

3.4.1.算法思想

进程的执行顺序由高优先级到低优先级,系统或用户按某种原则为进程指定一个优先级来表示该进程所享有的确调度优先权。

该算法核心是确定进程的优先级。

 

3.4.2.算法流程图

 

 

 

 

 

 

图3.4.优先级调度流程图

3.4.3.程序代码

voidCprogressDlg:

:

HPHS(void)

{

inti=0;

CreateProArray();//创建时间数组

while(!

IsFinish())

{

i=0;

//找出已创建的进程

while(!

IsCreate(m_pro[i])||m_pronode[m_pro[i]].prostate==FINISH)

{

++i;

if(i==5)

{

m_systime+=1;

i=0;

ProShow();//更新进程运行状态

}

}

//进程服务

for(intr=0;r

{

m_systime+=1;

m_pronode[m_pro[i]].finishpart+=1;

ProShow();//更新进程运行状态

}

m_pronode[m_pro[i]].prostate=FINISH;

}

}

3.5.基础函数

3.5.1.进度条设置

voidCprogressDlg:

:

ProSet(CProgressCtrl*proset,intser)

{

proset->SetRange32(0,ser);

proset->SetStep

(1);

proset->SetPos(0);

}

3.5.2.创建进程PBC

 

 

图3.5.2创建进程PBC流程图

voidCprogressDlg:

:

CreatePro(void)

{

intpro,cre,ser;

m_systime=0;

for(inti=0;i<5;++i)

{

pro=GetDlgItemInt(IDC_PRIORITY1+i);

cre=GetDlgItemInt(IDC_CREATE1+i);

ser=GetDlgItemInt(IDC_SERVE1+i);

m_pronode[i].pro=pro;

m_pronode[i].createtime=cre;

m_pronode[i].servetime=ser;

m_pronode[i].finishpart=0;

m_pronode[i].prostate=READY;

m_pronode[i].rr=-1;

}

}

3.5.3.更新进程运行状态显示

voidCprogressDlg:

:

ProShow(void)

{

CStringstr;

m_proctrl1.SetPos(m_pronode[0].finishpart);

str.Format(_T("%d"),m_pronode[0].finishpart);

GetDlgItem(IDC_STATIC1)->SetWindowTextW(str);

m_proctrl2.SetPos(m_pronode[1].finishpart);

str.Format(_T("%d"),m_pronode[1].finishpart);

GetDlgItem(IDC_STATIC2)->SetWindowTextW(str);

m_proctrl3.SetPos(m_pronode[2].finishpart);

str.Format(_T("%d"),m_pronode[2].finishpart);

GetDlgItem(IDC_STATIC3)->SetWindowTextW(str);

m_proctrl4.SetPos(m_pronode[3].finishpart);

str.Format(_T("%d"),m_pronode[3].finishpart);

GetDlgItem(IDC_STATIC4)->SetWindowTextW(str);

m_proctrl5.SetPos(m_pronode[4].finishpart);

str.Format(_T("%d"),m_pronode[4].finishpart);

GetDlgItem(IDC_STATIC5)->SetWindowTextW(str);

str.Format(_T("运行时间:

%d"),m_systime);

GetDlgItem(IDC_STATIC6)->SetWindowTextW(str);

Sleep(m_sleep);

}

3.5.4.判断当前进程是否创建

BOOLCprogressDlg:

:

IsCreate(intindex)

{

if(m_pronode[index].createtime>m_systime)

returnFALSE;

else

returnTRUE;

}

3.5.5.创建时间队列

 

图3.5.5创建时间队列流程图

voidCprogressDlg:

:

CreateTimeArray(void)

{

inttime=100,s;

for(intj=0;j<5;++j)

{

for(inti=0;i<5;++i)

{

if(m_pronode[i].createtime

{

time=m_pronode[i].createtime;

s=i;

}

}

m_pronode[s].rr=0;

m_time[j]=s;

time=100;

}

}

3.5.6.判断所有进程是否完成

BOOLCprogressDlg:

:

IsFinish(void)

{

intpronum=5,i;

//是否所有进程完成

for(i=0;i<5;++i){

if((m_pronode[i].prostate)==FINISH)

pronum-=1;

}

if(pronum!

=0)returnFALSE;

ElsereturnTRUE;

}

3.5.7.创建优先权队列

 

图3.5.7创建优先权队列流程图

voidCprogressDlg:

:

CreateProArray(void)

{

intpro=100,s=0;

for(intj=0;j<5;++j)

{

for(inti=0;i<5;++i)

{

if(m_pronode[i].pro

{

pro=m_pronode[i].pro;

s=i;

}

}

m_pronode[s].rr=0;

m_pro[j]=s;

pro=100;

}

}

3.5.8.先来先服务线程函数

UINTThreadFuncFCFS(LPVOIDlp)

{

criticalSection.Lock();

CprogressDlg*dlg;

dlg=(CprogressDlg*)lp;

dlg->CreatePro();

dlg->FCFS();

criticalSection.Unlock();

return0;

}

3.5.9.时间片轮转线程函数

UINTThreadFuncRR(LPVOIDlp)

{

criticalSection.Lock();

CprogressDlg*dlg;

dlg=(CprogressDlg*)lp;

dlg->CreatePro();

dlg->RR();

criticalSection.Unlock();

return0;

}

 

3.5.10.高优先级线程函数

UINTThreadFuncHPHS(LPVOIDlp)

{

criticalSection.Lock();

CprogressDlg*dlg;

dlg=(CprogressDlg*)lp;

dlg->CreatePro();

dlg->HPHS();

criticalSection.Unlock();

return0;

}

3.5.11.保存输入框修改线程函数

UINTThreadFuncSave(LPVOIDlp)

{

criticalSection.Lock();

CprogressDlg*dlg;

dlg=(CprogressDlg*)lp;

dlg->Save();

dlg->MessageBox(_T("修改成功!

"),_T("提示"),MB_OK);

criticalSection.Unlock();

return0;

}

3.5.12.保存输入框修改

voidCprogressDlg:

:

Save(void)

{

SendMessage(UM_MYUPDATEDATA,TRUE);

ProSet(&m_proctrl1,m_ser1);

ProSet(&m_proctrl2,m_ser2);

ProSet(&m_proctrl3,m_ser3);

ProSet(&m_proctrl4,m_ser4);

ProSet(&m_proctrl5,m_ser5);

GetDlgItem(IDC_STATIC1)->SetWindowTextW(_T("0"));

GetDlgItem(IDC_STATIC2)->SetWindowTextW(_T("0"));

GetDlgItem(IDC_STATIC3)->SetWindowTextW(_T("0"));

GetDlgItem(IDC_STATIC4)->SetWindowTextW(_T("0"));

GetDlgItem(IDC_STATIC5)->SetWindowTextW(_T("0"));

GetDlgItem(IDC_STATIC6)->SetWindowTextW(_T("运行时间:

0"));

}

3.5.13.子线程向主线程发送消息

afx_msgLRESULTCprogressDlg:

:

OnUmMyupdatedata(WPARAMwParam,LPARAMlParam)

{

UpdateData(wParam);

return0;

}

四.程序的调试与运行结果说明

4.1.界面

4.1.1问题1

程序界面出现“卡死”现象

原因,当程序只有一个主线程的时候,程序只有完成当前操作的时候才会执行下一个操作任务。

解决办法,分别添加四个线程,分别是保存修改线程,先来先服务线程,时间片轮转线程,高优先权优先服务线程。

图4.1.1界面调试

4.2.先来先服务调度

4.2.1问题1

无法正确按照时间先后顺序调用线程。

原因是直接修改PCB队列会导致界面的实现比较困难,但是不修改又会导致无法正确调度进程或者需要更多的函数辅助,以便实现相应的功能。

解决办法,创建时间队列,添加函数voidCprogressDlg:

:

CreateTimeArray(void)

图4.2.先来先服务调度调试

 

4.3.时间片轮转调度

4.3.1问题1

进程时间片结束还没有切换下一个线程。

解决办法

修改该段代码

m_systime+=1;

m_pronode[m_time[i]].finishpart+=1;

ProShow();//更新进程运行状态

改成如下代码

if(m_pronode[m_time[i]].finishpart==m_pronode[m_time[i]].s

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

当前位置:首页 > 幼儿教育 > 少儿英语

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

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