操作系统实验报告3.docx
- 文档编号:29864074
- 上传时间:2023-07-27
- 格式:DOCX
- 页数:18
- 大小:132.21KB
操作系统实验报告3.docx
《操作系统实验报告3.docx》由会员分享,可在线阅读,更多相关《操作系统实验报告3.docx(18页珍藏版)》请在冰豆网上搜索。
操作系统实验报告3
《操作系统》实验报告
实验序号:
3 实验项目名称:
作业调度的实现
学 号
1209030109
姓 名
陶爽
专业、班
信管1201
实验地点
文波331
指导教师
屈振新
时间
2013.12.24
一、实验目的及要求
在linux环境下,完成验证性实验——作业调度的实现。
二、实验设备(环境)及要求
(1)操作系统:
Linux
(2)开发环境:
Linux终端
(3)1G以上的CPU处理器,512MB以上的内存,10G的自由硬盘空间
三、实验内容与步骤
程序算法如下:
job.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include"job.h"
intjobid=0;
intsiginfo=1;
intfifo;
intglobalfd;
structwaitqueue*head=NULL;
structwaitqueue*next=NULL,*current=NULL;
voidschedule()
{
structjobinfo*newjob=NULL;
structjobcmdcmd;
intcount=0;
bzero(&cmd,DATALEN);
if((count=read(fifo,&cmd,DATALEN))<0)
error_sys("readfifofailed");
#ifdefDEBUG
if(count){
printf("cmdcmdtype\t%d\n"
"cmddefpri\t%d\n"
"cmddata\t%s\n",
cmd.type,cmd.defpri,cmd.data);
}else
printf("nodataread\n");
#endif
switch(cmd.type){
caseENQ:
do_enq(newjob,cmd);
break;
caseDEQ:
do_deq(cmd);
break;
caseSTAT:
do_stat(cmd);
break;
default:
break;
}
/*Updatejobsinwaitqueue*/
updateall();
/*selectthehighestpriorityjobtorun*/
next=jobselect();
/*stopcurrentjob,runnextjob*/
jobswitch();
}
intallocjid()
{
return++jobid;
}
voidupdateall()
{
structwaitqueue*p;
/*updaterunningjob'srun_time*/
if(current)
current->job->run_time+=1;/*add1represent100ms*/
/*updatereadyjob'swait_time*/
for(p=head;p!
=NULL;p=p->next){
p->job->wait_time+=100;
if(p->job->wait_time>=1000&&p->job->curpri<3)
p->job->curpri++;
}
}
structwaitqueue*jobselect()
{
structwaitqueue*p,*prev,*select,*selectprev;
inthighest=-1;
select=NULL;
selectprev=NULL;
if(head){
for(prev=head,p=head;p!
=NULL;prev=p,p=p->next)
if(p->job->curpri>highest){
select=p;
selectprev=prev;
highest=p->job->curpri;
}
selectprev->next=select->next;
if(select==selectprev)
head=NULL;
}
returnselect;
}
voidjobswitch()
{
structwaitqueue*p;
inti;
if(current&¤t->job->state==DONE){/*currentjobfinished*/
/*jobhasbeendone,removeit*/
for(i=0;(current->job->cmdarg)[i]!
=NULL;i++){
free((current->job->cmdarg)[i]);
(current->job->cmdarg)[i]=NULL;
}
free(current->job->cmdarg);
free(current->job);
free(current);
current=NULL;
}
if(next==NULL&¤t==NULL)/*nojobtorun*/
return;
elseif(next!
=NULL&¤t==NULL){/*startnewjob*/
//printf("beginstartnewjob\n");
current=next;
next=NULL;
current->job->state=RUNNING;
kill(current->job->pid,SIGCONT);
return;
}elseif(next!
=NULL&¤t!
=NULL){/*doswitch*/
//printf("beginswitch\n");
kill(current->job->pid,SIGSTOP);
current->job->curpri=current->job->defpri;
current->job->wait_time=0;
current->job->state=READY;
/*movebacktothequeue*/
if(head){
for(p=head;p->next!
=NULL;p=p->next);
p->next=current;
}else{
head=current;
}
current=next;
next=NULL;
current->job->state=RUNNING;
kill(current->job->pid,SIGCONT);
return;
}else{/*next==NULL&¤t!
=NULL,noswitch*/
return;
}
}
voidsig_handler(intsig,siginfo_t*info,void*notused)
{
intstatus;
intret;
switch(sig){
caseSIGVTALRM:
schedule();
return;
caseSIGCHLD:
ret=waitpid(-1,&status,WNOHANG);
if(ret==0)
return;
if(WIFEXITED(status)){
current->job->state=DONE;
printf("normaltermation,exitstatus=%d\n",WEXITSTATUS(status));
}/*elseif(WIFSIGNALED(status)){*/
/*printf("abnormaltermation,signalnumber=%d\n",WTERMSIG(status));*/
/*}elseif(WIFSTOPPED(status)){*/
/*printf("childstopped,signalnumber=%d\n",WSTOPSIG(status));*/
/*}*/
return;
default:
return;
}
}
voiddo_enq(structjobinfo*newjob,structjobcmdenqcmd)
{
structwaitqueue*newnode,*p;
inti=0,pid;
char*offset,*argvec,*q;
char**arglist;
sigset_tzeromask;
sigemptyset(&zeromask);
/*filljobinfostruct*/
newjob=(structjobinfo*)malloc(sizeof(structjobinfo));
newjob->jid=allocjid();
newjob->defpri=enqcmd.defpri;
newjob->curpri=enqcmd.defpri;
newjob->ownerid=enqcmd.owner;
newjob->state=READY;
newjob->wait_time=0;
newjob->run_time=0;
arglist=(char**)malloc(sizeof(char*)*(enqcmd.argnum+1));
newjob->cmdarg=arglist;
offset=enqcmd.data;
argvec=enqcmd.data;
while(i if(*offset==': '){ *offset++='\0'; q=(char*)malloc(offset-argvec); strcpy(q,argvec); arglist[i++]=q; argvec=offset; }else offset++; } arglist[i]=NULL; newjob->create_time=time(NULL); #ifdefDEBUG printf("enqcmdargnum%d\n",enqcmd.argnum); for(i=0;i printf("parseenqcmd: %s\n",arglist[i]); #endif /*addnewjobtothequeue*/ newnode=(structwaitqueue*)malloc(sizeof(structwaitqueue)); newnode->next=NULL; newnode->job=newjob; if(head){ for(p=head;p->next! =NULL;p=p->next); p->next=newnode; }else head=newnode; /*createprocessforthejob*/ if((pid=fork())<0) error_sys("enqforkfailed"); /*Inchildprocess*/ if(pid==0){ newjob->pid=getpid(); /*blockthechildwaitforrun*/ raise(SIGSTOP); #ifdefDEBUG printf("beginrunning\n"); for(i=0;arglist[i]! =NULL;i++) printf("arglist%s\n",arglist[i]); #endif /*duptheglobalfiledescriptortostdout*/ //dup2(globalfd,1); if(execv(arglist[0],arglist)<0) printf("execfailed\n"); exit (1); }else{ newjob->pid=pid; } } /*bugtofix*/ voiddo_deq(structjobcmddeqcmd) { intdeqid,i; structwaitqueue*p,*prev,*select,*selectprev; deqid=atoi(deqcmd.data); #ifdefDEBUG printf("deqjid%d\n",deqid); #endif /*currentjodid==deqid,terminatecurrentjob*/ if(current&¤t->job->jid==deqid){ printf("terminatecurrentjob\n"); kill(SIGTERM,current->job->pid); for(i=0;(current->job->cmdarg)[i]! =NULL;i++){ free((current->job->cmdarg)[i]); (current->job->cmdarg)[i]=NULL; } free(current->job->cmdarg); free(current->job); free(current); current=NULL; }else{/*maybeinwaitqueue,searchit*/ select=NULL; selectprev=NULL; if(head){ for(prev=head,p=head;p! =NULL;prev=p,p=p->next) if(p->job->jid==deqid){ select=p; selectprev=prev; break; } selectprev->next=select->next; if(select==selectprev) head=NULL; } if(select){ for(i=0;(select->job->cmdarg)[i]! =NULL;i++){ free((select->job->cmdarg)[i]); (select->job->cmdarg)[i]=NULL; } free(select->job->cmdarg); free(select->job); free(select); select=NULL; } } } voiddo_stat(structjobcmdstatcmd) { structwaitqueue*p; intstatfd; /* *Printjobstatisticsofalljobs: *1.jobid *2.jobpid *3.jobowner *4.jobruntime *5.jobwaittime *6.jobcreatetime *7.jobstate */ if((statfd=open("/tmp/stat",O_WRONLY))<0) error_sys("openfifofailed"); if(current){ write(statfd,current->job,sizeof(structjobinfo)); } for(p=head;p! =NULL;p=p->next){ write(statfd,p->job,sizeof(structjobinfo)); } close(statfd); } intmain() { structtimevalinterval; structitimervalnew,old; structstatstatbuf; structsigactionnewact,oldact1,oldact2; if(stat("/tmp/server",&statbuf)==0){ /*iffifofileexists,removeit*/ if(remove("/tmp/server")<0) error_sys("removefailed"); } if(mkfifo("/tmp/server",0666)<0) error_sys("mkfifofailed"); /*openfifoinnonblockmode*/ if((fifo=open("/tmp/server",O_RDONLY|O_NONBLOCK))<0) error_sys("openfifofailed"); /*openglobalfileforjoboutput*/ if((globalfd=open("/dev/null",O_WRONLY))<0) error_sys("openglobalfilefailed"); /*setupsignalhandler*/ newact.sa_sigaction=sig_handler; sigemptyset(&newact.sa_mask); newact.sa_flags=SA_SIGINFO; sigaction(SIGCHLD,&newact,&oldact1); sigaction(SIGVTALRM,&newact,&oldact2); /*timerinterval: 0s,100ms*/ interval.tv_sec=0; interval.tv_usec=100; new.it_interval=interval; new.it_value=interval; setitimer(ITIMER_VIRTUAL,&new,&old); while(siginfo==1); close(fifo); close(globalfd); return0; } 具体实现步骤: 1.将实验指导目录中linux下的os3中的src放在桌面上。 2.打开终端1,输入以下指令: 【cd./桌面/src】 【gccjob.cerror.c–ojob】 【gccenq.cerror.c-oenq】 【gccdeq.cerror.c-odeq】 【gccstat.cerror.c-ostat】 3.编写123.c和456.c两个死循环程序,编译运行无误,并改名生成程序P1,P2。 4.执行./job&指令将p2添加到p1中。 5.打开终端2 输入【cd./桌面/src】指令 执行【./stat】指令查看进程状态 反复调用【./stat】指令 6.交替执行指令【./enq】和【./deq】指令删除p1,p2并再次添加并调用【./stat】指令查看进程变化。 7.实验完成后调用【kill】指令结束进程。 运行截图如下: 四、实验结果与数据处理 加深了对作业的理解,掌握了基本的作业调度算法,理解了对于不同的系统和系统目标,通常采用不同的调度算法。 五、分析与讨论 六、教师评语 签名: 日期: 成绩
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 实验 报告