计算机操作系统实验报告.docx
《计算机操作系统实验报告.docx》由会员分享,可在线阅读,更多相关《计算机操作系统实验报告.docx(30页珍藏版)》请在冰点文库上搜索。
实验报告
(实验)课程名称计算机操作系统
11
实 验 报 告
学生姓名:
学号:
指导教师:
实验地点:
主楼A2-411实验时间:
2019.5
一、实验室名称:
计算机实验室
二、实验项目名称:
进程与资源管理三、实验学时:
6
四、实验原理:
(1)系统总体架构
最右边部分为进程与资源管理器,属于操作系统内核的功能。
该管理器具有如下功能:
完成进程创建、撤销和进程调度;完成多单元(multi_unit)资源的管理;完成资源的申请和释放;完成错误检测和定时器中断功能。
中间绿色部分为驱动程序testshell,设计与实现testshell,该testshell将调度所设计的进程与资源管理器来完成测试。
Testshell的应具有的功能:
1、从终端或者测试文件读取命令;
2、将用户需求转换成调度内核函数(即调度进程和资源管理器);
3、在终端或输出文件中显示结果:
如当前运行的进程、错误信息
(2)进程的基本三个状态
1、就绪状态,当进程已分配到除CPU以外的所有必要资源后,只要再获得CPU,就可以立即运行,进程这时的状态称为就绪状态。
2、执行状态,进程已获得CPU,其程序正在执行。
在单处理机系统中,只有一个进程处于执行状态,在多处理机系统中,则有多个进程处于执行状态。
3、阻塞状态,处于执行状态的线程由于发生某事件而暂停无法继续执行时,便放弃处理机而处于暂停状态,此时进程的状态称为阻塞状态,或等待状态或封锁状态。
(3)操作系统的资源管理
1、跟踪记录资源使用情况:
在多道任务系统中,系统资源要满足多道任务的需要,但一个任务对资源的需要可能并不是连续的,这就需要对资源使用情况进行跟踪和记录,了解当前资源状态或剩余情况,以满足任务对资源的请求。
2、分配或回收资源:
在条件满足的情况下将资源分配给请求的任务,分配后要记录当前资源剩余情况和状态,以备下一次的分配;根据任务完成的情况适时地回收系统资源,保证新进程的请求。
3、提高资源的利用率:
在操作系统的管理下使系统资源得到合理、高效的使用。
4、协调多个进程对资源请求的冲突:
当少量资源为多个请求服务时,会产生资源使用冲突,这时操作系统需要分析请求进程的特性,对资源使用做出决策,协调各进程合理地使用资源。
(4)进程调度与时钟中断设计
使用基于优先级的抢占式调度策略,在同一优先级内使用时间片轮转算法。
五、实验目的:
设计和实现进程与资源管理,并完成Testshell的编写,以建立系统的进程管理、调度、资源管理和分配的知识体系,从而加深对操作系统进程调度和资源管理功能的宏观理解和微观实现技术的掌握。
六、实验内容:
在实验室提供的软硬件环境中,设计并实现一个基本的进程与资源管理器。
该管理器能够完成进程的控制,如进程创建与撤销、进程的状态转换;能够基于优先级调度算法完成进程的调度,模拟时钟中断,在同优先级进程中采用时间片轮转调度算法进行调度;能够完成资源的分配与释放,并完成进程之间的同步。
该管理器同时也能完成从用户终端或者指定文件读取用户命令,通过Testshell模块完成对用户命令的解释,将用户命令转化为对进程与资源控制的具体操作,
并将执行结果输出到终端。
七、实验环境(设备、元器件):
1、操作系统:
Windows10
2、开发工具:
VisualStudio2017
八、实验步骤:
(一)系统功能需求分析:
创建进程、销毁进程、进程调度、请求资源、释放资源、时间中断
(二)总体框架设计
1、具体原理和总体工作流程分析:
首先,通过主函数从终端上读入各种命令,然后对命令进行分析,将用户的需求转换成调度内核函数,以实现创建进程、撤销进程、销毁调度、请求资源、释放资源、时间中断等功能,从而模拟操作系统对进程调度和资源管理的的过程,最后在终端上显示相对应的消息。
2、相关方法和算法:
(1)C语言中的结构struct,用来实现PCB、RCB等
(2)STL容器实现阻塞队列,就绪队列,并完成删除,插入等操作。
(3)将进程资源管理封装成一个类,主函数实现接收命令来调用这个类的对象。
3、总体工作流程图
开始
Managem;
Init()
getline(cin,line)istringstreaimss(line);
从终端上接收命令
Iss>>command
Command==create Command==delete Command==List Command==request Command==release Command==to
iss>>name>>unit; iss>>name>>unit;
Iss>>name
M.create(name)
Iss>>name
M.delete(name)
Iss>>kind
m.request(id,unit);m.release(id,unit);
m.timeout();
Kind==rl
Kind==pcb Kind==rcb
M.print_rl() M.print_pcb()M.print_rcb()
(三)模块详细设计几个全局变量:
RL为list容器来实现3种优先级的就绪队列,r[4]分别为R1,R2,R3,R4,四种
资源种类,current_process为全局变量,用来指示当前进程。
listRL[3];//就绪队列RCBr[4];//四种资源
PCB*current_process;//当前进程
1进程管理设计
1.1进程状态与操作
进程状态:
ready/running/blocked进程操作:
创建(create):
(none)->ready
撤销(destroy):
running/ready/blocked->(none)
请求资源(Request):
running->blocked(当资源没有时,进程阻塞)释放资源(Release):
blocked->ready(因申请资源而阻塞的进
程被唤醒)
时钟中断(Time_out):
running->ready
调度:
ready->running/running->ready1.2进程控制块结构(PCB)
structPCB
{
stringname;inttype;
intpriority;
vectorchildren;//孩子节点PCB*father; //父亲节点resourceres[4];
};
structresource
{
intused=0;//资源使用的数量
intwait_req=0;//因申请资源而导致进程被阻塞的资源数量
};
3个级别的优先级,且优先级固定无变化
2=“system”
1=“user”
0=“init”
每个PCB要么在RL中,要么在blocklist中。
当前正在运行的进程,根据优先级,可以将其放在RL中相应优先级队列的首部。
1.3创建进程函数
开始
Newprocess
赋优先级,PCB名字
连接父亲节点,子节点
压入相应优先级就绪队列
scheduler()
输出创建进程信息
结束
1、设计流程
2、详细代码
voidManage:
:
create(stringname,intpriority)
{
PCB*newprocess=newPCB;//创建新进程newprocess->name=name;
newprocess->priority=priority;
newprocess->father=current_process;//连接父亲节点process_list[name]=newprocess;
if(current_process!
=nullptr)
current_process->children.push_back(newprocess);//链接子节点RL[priority].push_back(newprocess);//进程进入相应优先级的就绪队列scheduler();
if(newprocess->name!
=current_process->name)newprocess->type=1;
cout<<"process"<name<<"isrunning"<}
1.4删除进程函数
开始
查找进程
kill(p)嵌套调用,撤销所有子孙进程
在父进程的子进程里删除自己
scheduler()
结束
1、设计流程
2、详细代码设计
voidManage:
:
destroy(stringname)
{
autoa=process_list.find(name);PCB*p=a->second;
kill(p);//嵌套调用,撤销所有子孙进程
autofather=p->father;
for(inti=0;ichildren.size();++i)//在父进程的子进程里删除自己
{
if(p->name==father->children[i]->name)
{
father->children.erase(father->children.begin()+i);break;
}
}
scheduler();
}
2资源管理设计
2.1资源控制块(RCB)的结构
structRCB
{
intinitial=0;//初始资源数量
intavailable=0;//剩余可用资源数量listwait_list;//资源对应的阻塞队列
};
2.2请求资源
当请求资源不超过该类资源现有数量时,给请求资源的进程分配资源,当请求资源超过该类资源现有数量时,将该进程放入对应资源的阻塞队列中。
开始
No
申请资源数<=现有量
当前进程状态变为阻塞
YES
r[id].available-=unit;process->res[id].used+=unit
压入对应资源的阻塞队列
输出相应信息
输出相应信息
scheduler()
结束
1、设计流程
2、详细代码设计
voidManage:
:
request(intid,intunit)
{
if(r[id].available>=unit)
{
r[id].available-=unit;current_process->res[id].used+=unit;
cout<<"process"<name<<"requests"<}
else
{
current_process->type=2;
RL[current_process->priority].remove(current_process);r[id].wait_list.push_back(current_process);
cout<<"process"<name<<"isblocked."<scheduler();
cout<<"process"<name<<"isrunning."<}
}
2.3释放资源
将资源r从当前进程占用的资源列表里移除,并且资源r的可用数量从u变为u+n,如果阻塞队列不为空,且阻塞队列首部进程需求的资源数req小于等于可用资源数量u,则唤醒这个阻塞进程,放入就绪队列。
1、设计流程
开始
进程占用资源释放
资源可用数增加
资源的阻塞队列不空&&资源可用数大于队列头部进程的wait_req
该进程和资源可用数相应改变
进程状态变为就绪
进程从阻塞队列移除
压入相应就绪队列
输出信息
scheduler()
结束
2、详细代码
voidManage:
:
release(intid,intunit,PCB*process=current_process)
{
process->res[id].used-=unit;r[id].available+=unit;
while(!
r[id].wait_list.empty()&&r[id].available>=r[id].wait_list.front()->res[id].wait_req)
{
autotemp=r[id].wait_list.front();
temp->res[id].used+=temp->res[id].wait_req;r[id].available-=temp->res[id].wait_req;temp->res[id].wait_req=0;r[id].wait_list.remove(temp);
temp->type=1;
RL[temp->priority].push_back(temp);
cout<<"Theprocess"<name<<"wakeup"<}
scheduler();
}
3进程调度与时钟中断设计
3.1进程调度
1、调度策略
基于3个优先级别的调度:
2,1,0,使用基于优先级的抢占式调度策略,在同一优先级内使用时间片轮转(RR),基于函数调用来模拟时间共享
2、设计流程
当前进程为空
NO
当前进程的优先级小于p
YES
抢占当前进程
YES
抢占当前进程
No
结束
开始
找到最高优先级进程p
3、详细代码
voidManage:
:
scheduler()
{
intmax=0;
if(!
RL[2].empty())max=2;
elseif(!
RL[1].empty())max=1;
if(current_process==nullptr)
{
current_process=RL[max].front();current_process->type=0;
}
elseif(current_process->priority{
RL[current_process->priority].remove(current_process);RL[current_process->priority].push_back(current_process);current_process->type=1;
current_process=RL[max].front();
current_process->type=0;
}
}
3.2时钟中断设计
开始
从就绪队列头部移除当前运行进程q
q的状态变为就绪
压入就绪队列尾部
scheduler()
输出相应信息
结束
1、设计流程
2、详细代码
voidManage:
:
timeout()
{
intp=current_process->priority;
RL[p].remove(current_process);RL[p].push_back(current_process);current_process->type=1;
autoa=current_process;current_process=nullptr;scheduler();
if(a->name!
=current_process->name)
cout<<"Nowtheprocess"<name<<"isready,"<<"theprocess"<name<<"isruning"<15
else
}
cout<<"Nowtheprocess"<name<<"isrunning"<4、系统初始化设计
初始化每个资源的数量,对应的阻塞队列和就绪队列,并创建init进程。
voidManage:
:
init()
{
current_process=nullptr;for(inti=0;i<4;++i)
{
r[i].initial=i+1;r[i].available=i+1;
while(!
r[i].wait_list.empty())
{
r[i].wait_list.pop_back();
}
}
for(inti=0;i<3;++i)
{
while(!
RL[i].empty())
RL[i].pop_back();
}
create("init",0);
}
5输出就绪队列信息函数
遍历每个List将各个就绪队列中的进程打印出来。
voidManage:
:
print_RL()
{
for(inti=0;i<3;++i)
{
cout<
";
intsize=RL[i].size();if(size==0)
cout<<"NULL"<else
{
for(list:
:
iteratorit=RL[i].begin();it!
=RL[i].end();++it)
{
if((*it)->type==0)continue;
cout<<(*it)->name<<"";
}
}
cout<}
}
6输出PCB信息函数
打印PCB的状态,状态,优先级,所请求的资源,父进程,子进程。
voidManage:
:
print_PCB(stringname)
{
autoi=process_list.find(name);PCB*process=i->second;
if(process->type==0)
cout<<"typeisrunning"<type==1)
cout<<"typeisready"<else
cout<<"typeisblocked"<cout<<"thepriorityis"<priority<name<<"resource:
"<{
cout<<"R"<res[i].used<}
cout<<"fatheris"<father->name<children.size()==0)
cout<name<<"hasnochildren"<else
{
cout<<"childrenis";
for(inti=0;ichildren.size();++i)
{
cout<children[i]->name<<"";
}
cout<}
}
7输出RCB信息函数
将每个资源所剩余的资源数量和所对应的阻塞队列中包含的进程名字打印出来。
voidManage:
:
print_rcb()
{
for(inti=0;i<4;++i)
{
cout<<"R"<
intsize=r[i].wait_list.size();if(size==0)
cout<<"NULL"<else
{
for(list:
:
iteratorit=r[i].wait_list.begin();it!
=
r[i].wait_list.end();++it)
{
if((*it)->type==0)continue;
cout<<(*it)->name<<"";
}
}
cout<}
}
8主函数设计
intmain()
{
stringline,command;
Managem;
stringname;intunit;
intpriority;stringkind;
while(getline(cin,line))
{
istringstreamiss(line);
if(!
line.empty()&&line.size()>1)
{
iss>>command;
if(command=="init")
{
m.init();
}
elseif(command=="quit")exit(0);
elseif(command=="create")
{
iss>>name>>priority;m.create(name,priority);
}
elseif(command=="list")
{
iss>>kind;
if(kind=="pcb")
{
iss>>name;m.print_PCB(name);
}
elseif(kind=="rl")m.print_RL();
elseif(kind=="rcb")m.print_rcb();
30
else
}
cout<<"error"<elseif(command=="request")
{
iss>>name>>un