操作系统实验报告3
- 格式:doc
- 大小:121.50 KB
- 文档页数:9
操作系统实习报告 日期:2009-5-25 实习题目: 作业调度系统 完成 人 姓名: 组号:一 学号:
实习内容简要描述 1. 实验内容: 要求实现用户空间内的作业调度系统,通过作业调度系统实现以下的操作: (1)提交自己的作业。 (2)将自己提交的作业移出。 (3)查看作业状态。 2.实验目的: (1).理解操作系统中调度的概念和调度算法。 (2).学习Linux下进程控制以及进程之间通信的知识。 (3).理解在操作系统中作业是如何被调度的,如何协调和控制各作业对CPU的使用。 3.实验环境: windows 2000/xp ,Linux系统虚拟机 主要代码结构 (附注释) 见附表(一)
结果分析(或错误原因分析) 一.实验方法 要完成实验作业调度系统,还需要编写实验代码。在linux系统终端中,写一个可以执行的作业。下面将一个作业的代码写出来。
注释:如果上述表格空间不够,可以另附表格进行说明 结果分析(或错误原因分析) 将让面的程序保存为p1.c。接下来就在linux系统终端中进行处理。 1. 打开一终端,编译scheduler.c ,stat.c ,enq.c,deq.c文件。 2. 自己定义5个程序,为p1,p2,p3,p4,p5, 这5个程序 运行时间满足大于100毫秒,编译这个5个程序。 3. 当上面的工作完成后,在一个终端”A”里面运行”./scheduler”程序,然后再开一个终端”B”,运行“./enq p1 ”,同理,运行p2,p3,p4,p5, 也可以运行stat jid 和deq jid 命令,在A终端里面观察相对应的变化。结果如下 终端B
终端A
二.结果分析 1.当在A终端中运行scheduler程序后,结果如下
表明Scheduler程序已经运行。 2. 在B终端中运行./enq p1。在A终端中出现如下的结果: 表明新的job已经建立。Jid为1,pid为16914. 3. 在B终端中运行./stat。在A终端中出现如下结果 :
即显示作业状态。 4.在B终端运行./deq 后,在A终端出现如下结果。
表明作业已经出队。在终端B执行p2,p3,p4,p5后将出现与执行p1后相似的结果。
主要代码结构(附注释) 一:实验代码分析 此次试验中需要文件shceduler.c,deq.c,stat.c,enq.c和job.h.。其中shceduler.c是已经完成好的作业调度程序。下面分析它的代码shceduler.c。scheduler是作业调度程序,负责整个系统的运行。这是一个不断循环运行的进程,其任务是处理作业的入队、出队以及状态查看请求,在合适的时间调度各作业运行。 void schedule() { struct jobinfo *newjob = NULL;//创建一个新的jobinfo结构,用来存放job的信息 struct jobcmd cmd;//创建一个新的命令行结构,用来存放job命令的相关信息,包含命令种类,命令优先级,命令的发出者,命令的内容 int count = 0; bzero(&cmd, DATALEN);//该函数将命令行第一个命令置为空 if ((count = read(fifo, &cmd, DATALEN)) < 0)//读fifo文件中的一个job命令。 error_sys("read fifo failed"); //////////////////////////////////////////////////////////// switch (cmd.type) {//查看job命令行中的的type一项。该项代表此命令行的种类,即stat、 deq、enq命令。 case ENQ://如果是ENQ则调用enq命令相应的处理程序do_enq()函数处理 do_enq(newjob,cmd); break; case DEQ://如果是DEQ,则调用deq命令相对应的程序do_deq()函数处理 do_deq(cmd); break; case STAT://如果是STAT,则调用STAT命令相对应的程序do_stat()函数处理 do_stat(cmd); break; default://如果命令是其他命令,则什么都不做 break; } /*schedule()函数通过以上分析的形式对命令的类型进行分析,并调用与类型相对应的处理程序来进行作业调度任务。以下分析这三个处理程序。 void do_enq(struct jobinfo *newjob, struct jobcmd enqcmd)//此函数就是处理enq命令的程序。首先在程序中创建两个个waitqueue *newnode, *p;然后就进行newjob的填充,并进行命令的处理。如:*/ while (i < enqcmd.argnum) { if (*offset == ':') { *offset++ = '\0'; q = (char*)malloc(offset - argvec); strcpy(q,argvec); arglist[i++] = q; argvec = offset; } else offset++; } //在对命令行进行处理后,就应该将作业做入队处理。代码如下 newnode = (struct waitqueue*)malloc(sizeof(struct waitqueue)); newnode->next = NULL; newnode->job = newjob; //最后输出作业相关信息后整个处理就结束了。打印信息代码如下 newjob->pid = pid; printf("\nnew job: jid=%d, pid=%d\n", newjob->jid, newjob->pid); void do_deq(struct jobcmd deqcmd) //这个函数就是deq命令的处理函数。毫无疑问,这个函数首先也需要创//建作业等待队列 。 struct waitqueue *p,*prev,*select,*selectprev;//程序根据jid来确//定出队的job。首先会在当前正在执行的job中查找,如果符合,则直接进行一下处理 printf("terminate job: %d\n", current->job->jid); 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; //如果不是当前正在执行的job,则在等待队列中查找。 //在等待队列中找到后,程序就会将job停止,并释放job占用的资源。 void do_stat()//分析 //Stat命令就是在标准输出上打印出就绪队列中各作业的信息。实现相对//简单。只需要在等待队列中依次输出job的相关信息即可。 二:deq.c 和stat.c编写 deq.c和stat.c分别执行作业调度系统中的deq命令和stat命令。即作业出栈命令和作业状态查询命令。 deq是作业出队命令: 格式是deq jid, 每一个作业提交时,scheduler调度程序都将为其分配一个惟一的jid。使用deq命令,给scheduler调度程序发出一个出队请求。scheduler调度程序将使该作业出队,然后清除相关的数据结构。如果该作业当前正在运行,则发信号给它,迫使它停止运行。当然,每个用户都只能杀掉(kill)自己提交的作业,而非别人的。 stat是查看作业状态的命令: 格式是stat,在标准输出上打印出就绪队列中各作业的信息。状态信息应该包括如下几点: · 进程的pid; · 作业提交者的user name; · 作业执行的时间; · 在就绪队列中总的等待时间; · 作业创建的时刻; · 此时作业的状态(READY、RUNNING)。 在读了作业调度源代码scheduler.c文件后,分析enq.c文件, 根据enq.c的写法编写程序deq.c和stat.c,这两个程序就是判断输入的命令行是否是合法命令,如果不是,做出提示;如果是就将该命令存入FIFO文件中。然后scheduler.c程序就会在该文件中提取命令行,做出相应的处理。 //stat.c的源代码 void usage()//如果参数个数不对则调用该函数显示正确的命令格式提醒用户输入正确的命令 { printf ("Usage: stat\n" "Print job statistics of all jobs"); }
int main (int argc, char *argv[])//主函数 { struct jobcmd statcmd;// 命令行数据结构, int fd, fifo; char fifoname[100]; struct jobinfo info; char timebuf[BUFLEN]; if (argc != 1) { usage(); return 1; } statcmd.type = STAT; statcmd.defpri = 0; statcmd.owner = getuid(); statcmd.argnum = 0; statcmd.data[0]='\0'; if ((fd = open(FIFO, O_WRONLY)) < 0)