操作系统实验内容.docx
《操作系统实验内容.docx》由会员分享,可在线阅读,更多相关《操作系统实验内容.docx(42页珍藏版)》请在冰豆网上搜索。
![操作系统实验内容.docx](https://file1.bdocx.com/fileroot1/2023-2/21/bb1c77c4-47ed-44bb-9930-53efe7e6747e/bb1c77c4-47ed-44bb-9930-53efe7e6747e1.gif)
操作系统实验内容
计算机操作系统
实验报告
学号:
410
姓名:
提交日期:
2012-11-16
成绩:
东北大学秦皇岛分校
实验一进程的创建和控制
1、实验目的
通过进程的创建、撤销和运行加深对进程概念和进程并发执行的理解,明确进程与程序之间的区别。
2、实验内容
(1)了解系统调用fork()、exec()、exit()、和waitpid()的功能和实现过程。
(2)编写一段程序,使用系统调用fork()来创建两个子进程,并由父进程重复显示字符串“parent:
”和自己的标识数,而子进程则重复显示字符串“child:
”和自己的标识数。
#include
main()
{
intp,i;
while((p=fork())==-1);//创建子进程直至成功
if(p==0)//子进程返回
{
for(i=0;i<5;i++)
{
printf("Thechildprocess!
\n");
sleep
(1);
}
}
else{//父进程返回
for(i=0;i<5;i++)
{
printf("Theparentprocess!
\n");
sleep
(1);
}
}
}
(3)编写一段程序,使用系统调用fork()来创建一个子进程。
子进程通过系统调用exec()更换自己的执行代码,显示新的代码“newprogram.”后,调用exit()结束。
而父进程则调用waitpid()等待子进程结束,并在子进程结束后显示子进程的标示符,然后正常结束。
#include
#include
#include
#include
intmain(){
pid_tpid;
intresult;
pid=fork();
if(pid<0)
printf("forkerror");
elseif(pid==0)
{
printf("newprogram.\n");
execl("/root/fork.out","fork.out",0);
exit(0);
}
else{
inte=waitpid(pid,&result,0);
printf("ChildprocessPID:
%d.\n",e);
exit(0);
}
}
实验二使用动态优先权的进程调度算法模拟
1、实验目的
通过动态优先权算法的模拟加深对进程概念进程调度过程的理解。
2、实验内容
(1)用C语言来实现对N个进程采用动态优先权优先算法的进程调度。
(2)每个用来标识进程的进程控制块PCB用结构来描述,包括以下字段:
••••进程标识数ID。
••••进程优先数PRIORITY,并规定优先数越大的进程,其优先权越高。
••••进程已占用的CPU时间CPUTIME。
••••进程还需占用的CPU时间ALLTIME。
当进程运行完毕时,ALLTIME变为0。
••••进程的阻塞时间STARTBLOCK,表示当进程再运行STARTBLOCK个时间片后,将进入阻塞状态。
••••进程被阻塞的时间BLOCKTIME,表示已足赛的进程再等待BLOCKTIME个时间片后,将转换成就绪状态。
••••进程状态START。
••••队列指针NEXT,用来将PCB排成队列。
(3)优先数改变的原则:
•••进程在就绪队列中呆一个时间片,优先数加1。
•••进程每运行一个时间片,优先数减3。
(4)假设在调度前,系统中有5个进程,它们的初始状态如下:
ID
0
1
2
3
4
PRIORITY
9
38
30
29
0
CPUTIME
0
0
0
0
0
ALLTIME
3
3
6
3
4
STARTBLOCK
2
-1
-1
-1
-1
BLOCKTIME
3
0
0
0
0
STATE
READY
READY
READY
READY
READY
(5)为了清楚的观察各进程的调度过程,程序应将每个时间片内的情况显示出来,参照的具体格式如下:
RUNNINGPROG:
i
READY-QUEUE:
-〉id1-〉id2
BLOCK-QUEUE:
-〉id3-〉id4
=======================================
ID01234
PRIORITYP0P1P2P3P4
CUPTIMEC0C1C2C3C4
ALLTIMEA0A1A2A3A4
STARTBLOCKT0T1T2T3T4
BLOCKTIMEB0B1B2B3B4
STATES0S1S2S3S4
程序代码
#include
#include
usingnamespacestd;
inti;//循环值
intj;//还在阻塞或就绪队列中的进程数
ints;
intm;//最大priority的id
structpcb
{
intid;
intpriority;//优先级
intcputime;//CPU时间
intalltime;//进程还需占用的CPU时间
intstartblock;//进程的阻塞时间
intblocktime;//进程被阻塞的时间
intstate;//0表示ready1表示end-1表示block
};
structpcbprocess[5]={
{0,9,0,3,2,3,0},
{1,38,0,3,-1,0,0},
{2,30,0,6,-1,0,0},
{3,29,0,3,-1,0,0},
{4,0,0,4,-1,0,0}
};
intchangestate0()
{
if(process[0].startblock==0)
{
process[0].state=-1;
process[0].startblock--;
return1;
}
if(process[0].blocktime==0)
{
process[0].state=0;
return1;
}
if(process[0].state==0&&process[0].startblock!
=-1)
{
process[0].startblock--;
return1;
}
if(process[0].state==-1&&process[0].blocktime!
=0)
{
process[0].blocktime--;
return1;
}
}
intstate0()
{
changestate0();
s=process[0].priority;
if(process[0].state==-1)s=-100;
returns;
}
intmaxp()//求出最大priority
{
state0();
intmax=s;
m=process[0].id;
for(i=0;i{
if(process[i+1].priority>process[i].priority)
{
max=process[i+1].priority;
m=process[i+1].id;
}
}
returnm;
}
voidchange()
{
maxp();
intx;//得到m现在的数组编号
for(i=0;i{
process[i].priority++;//进程在就绪队列中呆一个时间片,优先数加1
}
for(i=0;i{
if(process[i].id==m)x=i;
}
process[x].cputime++;
process[x].priority=process[x].priority-4;//进程每运行一个时间片,优先数减3,因为前面已经加1,所以减4
process[x].alltime--;
if(process[x].alltime==0)process[x].state=1;
}
voiddisplay()
{
change();
cout<<"RUNNINGPROG:
"<cout<<"READY-QUEUE:
";
for(i=0;i{
if(process[i].state==0)cout<<"->"<}
cout<";
for(i=0;i{
if(process[i].state==-1)cout<<"->"<}
cout<cout<<"===============================================================\n";
cout<<"ID";
cout.width(15);
cout<for(i=1;i{
cout.width(10);
cout<}
cout<cout.width(9);
cout<for(i=1;i{
cout.width(10);
cout<}
cout<for(i=0;i{
cout.width(10);
cout<}
cout<for(i=0;i{
cout.width(10);
cout<}
cout<cout.width(8);
cout<for(i=1;i{
cout.width(10);
cout<}
cout<cout.width(8);
cout<for(i=1;i{
cout.width(10);
cout<}
cout<cout.width(12);
cout<for(i=1;i{
cout.width(10);
cout<}
cout<}
intmain()
{
j=5;//刚开始有5个进程
while(j!
=0)
{
display();
getchar();
for(i=0;i{
if(process[i].state==1){
for(;i{
process[i]=process[i+1];}
j=j-1;
}
}
}
}
运行结果
1.初始状态
2.调用进程一
3调用进程二
3调用进程三
实验三使用动态分区分配方式的模拟
1、实验目的
了解动态分区分配方式中使用的数据结构和分配算法,并进一步加深对动态分区存储管理方式及其实现过程的理解。
2、实验内容
(1)用C语言分别实现采用首次适应算法和最佳适应算法的动态分区分配过程alloc()和回收过程free()。
其中,空闲分区通过空闲分区链来管理:
在进行内存分配时,系统优先使用空闲区低端的空间。
(2)假设初始状态下,可用的内存空间为640KB,并有下列的请求序列:
•作业1申请130KB。
•作业2申请60KB。
•作业3申请100KB。
•作业2释放60KB。
•作业4申请200KB。
•作业3释放100KB。
•作业1释放130KB。
•作业5申请140KB。
•作业6申请60KB。
•作业7申请50KB。
•作业6释放60KB。
请分别采用首次适应算法和最佳适应算法,对内存块进行分配和回收,要求每次分配和回收后显示出空闲分区链的情况。
程序代码
#include
#include
#defineFree0//空闲状态
#defineBusy1//已用状态
#defineOK1//完成
#defineERROR0//出错
#defineMAX_length640//最大内存空间为640KB
typedefintStatus;
typedefstructfreearea//定义一个空闲区说明表结构
{
intID;//分区号
longsize;//分区大小
longaddress;//分区地址
intstate;//状态
}ElemType;
//----------线性表的双向链表存储结构------------
typedefstructDuLNode//doublelinkedlist
{
ElemTypedata;
structDuLNode*prior;//前趋指针
structDuLNode*next;//后继指针
}DuLNode,*DuLinkList;
DuLinkListblock_first;//头结点
DuLinkListblock_last;//尾结点
Statusalloc(int);//内存分配
Statusfree(int);//内存回收
StatusFirst_fit(int,int);//首次适应算法
StatusBest_fit(int,int);//最佳适应算法
voidshow();//查看分配
StatusInitblock();//开创空间表
StatusInitblock()//开创带头结点的内存空间链表
{
block_first=(DuLinkList)malloc(sizeof(DuLNode));
block_last=(DuLinkList)malloc(sizeof(DuLNode));
block_first->prior=NULL;
block_first->next=block_last;
block_last->prior=block_first;
block_last->next=NULL;
block_last->data.address=0;
block_last->data.size=MAX_length;
block_last->data.ID=0;
block_last->data.state=Free;
returnOK;
}
//-----------------------分配主存-------------------------
Statusalloc(intch)
{
intID,request;
cout<<"请输入作业(分区号):
";
cin>>ID;
cout<<"请输入需要分配的主存大小(单位:
KB):
";
cin>>request;
if(request<0||request==0)
{
cout<<"分配大小不合适,请重试!
"<returnERROR;
}
if(ch==2)//选择最佳适应算法
{
if(Best_fit(ID,request)==OK)cout<<"分配成功!
"<elsecout<<"内存不足,分配失败!
"<returnOK;
}
else//默认首次适应算法
{
if(First_fit(ID,request)==OK)cout<<"分配成功!
"<elsecout<<"内存不足,分配失败!
"<returnOK;
}
}
//------------------首次适应算法-----------------------
StatusFirst_fit(intID,intrequest)//传入作业名及申请量
{
//为申请作业开辟新空间且初始化
DuLinkListtemp=(DuLinkList)malloc(sizeof(DuLNode));
temp->data.ID=ID;
temp->data.size=request;
temp->data.state=Busy;
DuLNode*p=block_first->next;
while(p)
{
if(p->data.state==Free&&p->data.size==request)
{//有大小恰好合适的空闲块
p->data.state=Busy;
p->data.ID=ID;
returnOK;
break;
}
if(p->data.state==Free&&p->data.size>request)
{//有空闲块能满足需求且有剩余"
temp->prior=p->prior;
temp->next=p;
temp->data.address=p->data.address;
p->prior->next=temp;
p->prior=temp;
p->data.address=temp->data.address+temp->data.size;
p->data.size-=request;
returnOK;
break;
}
p=p->next;
}
returnERROR;
}
//--------------------最佳适应算法------------------------
StatusBest_fit(intID,intrequest)
{
intch;//记录最小剩余空间
DuLinkListtemp=(DuLinkList)malloc(sizeof(DuLNode));
temp->data.ID=ID;
temp->data.size=request;
temp->data.state=Busy;
DuLNode*p=block_first->next;
DuLNode*q=NULL;//记录最佳插入位置
while(p)//初始化最小空间和最佳位置
{
if(p->data.state==Free&&
(p->data.size>request||p->data.size==request))
{
q=p;
ch=p->data.size-request;
break;
}
p=p->next;
}
while(p)
{
if(p->data.state==Free&&p->data.size==request)
{//空闲块大小恰好合适
p->data.ID=ID;
p->data.state=Busy;
returnOK;
break;
}
if(p->data.state==Free&&p->data.size>request)
{//空闲块大于分配需求
if(p->data.size-request{
ch=p->data.size-request;//更新剩余最小值
q=p;//更新最佳位置指向
}
}
p=p->next;
}
if(q==NULL)returnERROR;//没有找到空闲块
else
{//找到了最佳位置并实现分配
temp->prior=q->prior;
temp->next=q;
temp->data.address=q->data.address;
q->prior->next=temp;
q->prior=temp;
q->data.address+=request;
q->data.size=ch;
returnOK;
}
}
//-----------------------内存回收--------------------
Statusfree(intID)
{
DuLNode*p=block_first;
while(p)
{
if(p->data.ID==ID)
{
p->data.state=Free;
p->data.ID=Free;
if(p->prior->data.state==Free)//与前面的空闲块相连
{
p->prior->data.size+=p->data.size;
p->prior->next=p->next;
p->next->prior=p->prior;
}
if(