《操做系统》实验之进程调度

实验内容:

第一部分:做业调度ios

   做业名算法

要求运行时间ide

   优先级ui

  到达时间spa

  连接指针操作系统

JCB设计

   提示:指针

   (1)假设系统有五个做业,每个做业投入内存后,操做系统仅为其创建一个进程.日志

      做业名      ----做业标识code

      要求运行时间----即估计的做业运行时间

      优先级      ----为之建立进程的基本优先级

      到达时间    ----做业提交的时刻,可用相对时间片时间表示

         /*以上三项可随机产生(+1)或用户指定*/

      连接指针    ----指向比本做业晚到来或同时到来而运行时间较短的做业

   (2)建立做业后应造成按主关键字为到达时间, 次关键字为要求运行时间的做业后备队列.

   (3)设置系统计时域,记录运行过的时间片个数,当它的值与做业后备队列队首的一个或多个做业的到达时间一致时,将它(们)投入就绪队列.

   (4)应有显示或打印语句,能显示或打印每通过一个系统时间后,就绪队列及做业后备队列的状态.

 

第二部分:进程调度

   (一)优先级调度:

   进程名

  连接指针

要求运行时间

   优先级

  进程状态

                      PCB

   提示:

      (1)

优先级     ----做业投入就绪队列,为其建立进程时将做业的基本优先级写入,调度时老是选择优先级最高的进程运行

进程名      ----为做业建立进程时起的名称

连接指针    ----指向就绪队列的下一个进程,就绪队列以优先级为基础排序

要求运行时间----进程运行的相对时间片时间,由为之建立进程的做业处获得

进程状态    ----为简单起见,假定进程仅有就绪和完成状态.进程建立时处于就绪态’R’,运行结束后,置为完成状态’C’,并从就绪队列中删除.

    (2)为调度方便,设置一个指针指向就绪队列的第一个进程.

    (3)处理机调度时,选择队首进程运行……将队首进程摘除后,运行一个时间片,即执行优先级减1、时间片减一的工做. 若此时要求运行时间为0:此进程运行完毕,状态置为’C’;若不为0,则比较其优先级与队首进程的优先级:当大于等于队首进程的优先级时,继续执行一个时间片,直至小于队首进程的优先级为止,将其插入到就绪队列的合适位置上,再调度队首进程投入运行.

   (4)所设计的程序应有显示或打印语句,显示或打印选中进程的进程名及运行一次后进程就绪队列及后备做业队列的状态.

(二)时间片轮转法:(+2)

   进程名

  连接指针

要求运行时间

  进程状态

   PCB

   提示:

   (1)连接指针----指向下一个到来进程的PCB首地址,最后一个进程指出第一个进程的PCB首地址.

         其它如上题

   (2)设置一个队首指针指向就绪循环队列的队首进程.如有新的进程到来,则将其插入到就绪循环队列的尾端,等待下次调度.

   (3)执行处理机调度时,老是选择队首进程运行.仅执行要求运行时间减一的工做.

   (4)进程运行一次后,判断运行时间是否为0:若为0,则置状态为’C’,并推出循环就绪队列;若不为0,将其置于循环队列的尾端,等待下一轮的运行.

   (5)若就绪队列不空,反复执行(3)、(4)步骤,直至全部进程都运行完为止.

   (6)所设计的调度程序中,应包含显示或打印语句,以便显示或打印每次选中的进程名及运行一次后进程就绪队列和做业后备队列的变化状况.

实现:

  我并无彻底按照实验内容来作。

  实现的算法是短进程优先以及时间片轮转,进程由做业生成。

程序流程以下:

  一、首先随机生成多个做业,对生成的做业按到达时间排序。

  二、时间片轮转开始。

  三、检查就绪队列、后备队列、做业调度表是否都为空。若是是,跳到7,程序结束,不然继续执行。

  四、检查是否有做业到达。如有做业到达,将做业投入后备队列,并按短进程优先排序,同时检查就绪队列是否已满。若是没有做业到达,则进行下一步。

  五、若是就绪队列不满,且后备队列不为空,则将后备队列队首转换为进程投入就绪队列队尾;后备队列为空,则不作处理。若是就绪队列已满,则进行下一步。

  六、提取就绪队列队首进程放入运行队列,将其运行时间-1,而后检查运行时间是否为0。若运行时间为0,将进程投入已完成队列队尾;若运行时间不为0,将进程投入回就绪队列队尾。

  七、程序结束。

程序中有5种队列,做业调度表,后备队列,就绪队列,运行队列,已完成队列。

  做业调度表:存放生成的做业,按到达时间从小到大排序。

  后备队列:存放虽然已到达,但尚未参与处理机资源分配的做业。

  就绪队列:存放已到达,且已参与处理机资源分配的做业。轮转分配资源。

  运行队列:存放当前正在运行的队列。同一时间,该队列最多有一个进程(单处理机)

  已完成队列:存放运行时间为0,即已完成的做业。

实验结果:

  

  

  

  

  此为运行结果的一部分,完整版能够见下(因为是随机生成做业,因此完整版和截图并不相同):

    --- 做业调度表 --- 做业名 到达时间 工做时间 Job6 2        1 Job2 2        8 Job9 3        6 Job7 5        3 Job4 6        2 Job3 6        2 Job1 7        1 Job5 8        2 Job8 9        1 # 开始时间片轮转 ------------------------------------------------------ 当前系统时间 : 1 # 无做业到达 # 就绪队列: => 空 # 已完成进程队列: => 空 # 后备队列: =>------------------------------------------------------ 当前系统时间 : 2 # 将做业Job6投入到后备队列 # 将做业Job2投入到后备队列 # 将做业Job6投入到就绪队列 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process6 1 W --- 后备队列 --- 做业名 到达时间 工做时间 Job2 2        8    

    --- 做业调度表 --- 做业名 到达时间 工做时间 Job9 3        6 Job7 5        3 Job4 6        2 Job3 6        2 Job1 7        1 Job5 8        2 Job8 9        1 # 进程Process6已完成,退出就绪队列 # 就绪队列: => 空 # 已完成进程队列: => Process6 # 后备队列: => Job2 ------------------------------------------------------ 当前系统时间 : 3 # 将做业Job9投入到后备队列 # 将做业Job9投入到就绪队列 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process9 6 W --- 后备队列 --- 做业名 到达时间 工做时间 Job2 2        8    

    --- 做业调度表 --- 做业名 到达时间 工做时间 Job7 5        3 Job4 6        2 Job3 6        2 Job1 7        1 Job5 8        2 Job8 9        1 # 就绪队列: => Process9 # 已完成进程队列: => Process6 # 后备队列: => Job2 ------------------------------------------------------ 当前系统时间 : 4 # 无做业到达 # 将做业Job2投入到就绪队列 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process9 5 W Process2 8 R --- 后备队列 --- 做业名 到达时间 工做时间 --- 做业调度表 --- 做业名 到达时间 工做时间 Job7 5        3 Job4 6        2 Job3 6        2 Job1 7        1 Job5 8        2 Job8 9        1 # 就绪队列: => Process2->Process9 # 已完成进程队列: => Process6 # 后备队列: =>------------------------------------------------------ 当前系统时间 : 5 # 将做业Job7投入到后备队列 # 将做业Job7投入到就绪队列 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process2 8 W Process9 4 R Process7 3 R --- 后备队列 --- 做业名 到达时间 工做时间 --- 做业调度表 --- 做业名 到达时间 工做时间 Job4 6        2 Job3 6        2 Job1 7        1 Job5 8        2 Job8 9        1 # 就绪队列: => Process9->Process7->Process2 # 已完成进程队列: => Process6 # 后备队列: =>------------------------------------------------------ 当前系统时间 : 6 # 将做业Job4投入到后备队列 # 将做业Job3投入到后备队列 # 将做业Job3投入到就绪队列 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process9 4 W Process7 3 R Process2 7 R Process3 2 R --- 后备队列 --- 做业名 到达时间 工做时间 Job4 6        2    

    --- 做业调度表 --- 做业名 到达时间 工做时间 Job1 7        1 Job5 8        2 Job8 9        1 # 就绪队列: => Process7->Process2->Process3->Process9 # 已完成进程队列: => Process6 # 后备队列: => Job4 ------------------------------------------------------ 当前系统时间 : 7 # 将做业Job1投入到后备队列 # 将做业Job1投入到就绪队列 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process7 3 W Process2 7 R Process3 2 R Process9 3 R Process1 1 R --- 后备队列 --- 做业名 到达时间 工做时间 Job4 6        2    

    --- 做业调度表 --- 做业名 到达时间 工做时间 Job5 8        2 Job8 9        1 # 就绪队列: => Process2->Process3->Process9->Process1->Process7 # 已完成进程队列: => Process6 # 后备队列: => Job4 ------------------------------------------------------ 当前系统时间 : 8 # 将做业Job5投入到后备队列 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process2 7 W Process3 2 R Process9 3 R Process1 1 R Process7 2 R --- 后备队列 --- 做业名 到达时间 工做时间 Job5 8        2 Job4 6        2    

    --- 做业调度表 --- 做业名 到达时间 工做时间 Job8 9        1 # 就绪队列: => Process3->Process9->Process1->Process7->Process2 # 已完成进程队列: => Process6 # 后备队列: => Job5->Job4 ------------------------------------------------------ 当前系统时间 : 9 # 将做业Job8投入到后备队列 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process3 2 W Process9 3 R Process1 1 R Process7 2 R Process2 6 R --- 后备队列 --- 做业名 到达时间 工做时间 Job8 9        1 Job5 8        2 Job4 6        2    

    --- 做业调度表 --- 做业名 到达时间 工做时间 # 就绪队列: => Process9->Process1->Process7->Process2->Process3 # 已完成进程队列: => Process6 # 后备队列: => Job8->Job5->Job4 ------------------------------------------------------ 当前系统时间 : 10 # 无做业到达 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process9 3 W Process1 1 R Process7 2 R Process2 6 R Process3 1 R --- 后备队列 --- 做业名 到达时间 工做时间 Job8 9        1 Job5 8        2 Job4 6        2    

    --- 做业调度表 --- 做业名 到达时间 工做时间 # 就绪队列: => Process1->Process7->Process2->Process3->Process9 # 已完成进程队列: => Process6 # 后备队列: => Job8->Job5->Job4 ------------------------------------------------------ 当前系统时间 : 11 # 无做业到达 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process1 1 W Process7 2 R Process2 6 R Process3 1 R Process9 2 R --- 后备队列 --- 做业名 到达时间 工做时间 Job8 9        1 Job5 8        2 Job4 6        2    

    --- 做业调度表 --- 做业名 到达时间 工做时间 # 进程Process1已完成,退出就绪队列 # 就绪队列: => Process7->Process2->Process3->Process9 # 已完成进程队列: => Process6->Process1 # 后备队列: => Job8->Job5->Job4 ------------------------------------------------------ 当前系统时间 : 12 # 无做业到达 # 将做业Job8投入到就绪队列 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process7 2 W Process2 6 R Process3 1 R Process9 2 R Process8 1 R --- 后备队列 --- 做业名 到达时间 工做时间 Job5 8        2 Job4 6        2    

    --- 做业调度表 --- 做业名 到达时间 工做时间 # 就绪队列: => Process2->Process3->Process9->Process8->Process7 # 已完成进程队列: => Process6->Process1 # 后备队列: => Job5->Job4 ------------------------------------------------------ 当前系统时间 : 13 # 无做业到达 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process2 6 W Process3 1 R Process9 2 R Process8 1 R Process7 1 R --- 后备队列 --- 做业名 到达时间 工做时间 Job5 8        2 Job4 6        2    

    --- 做业调度表 --- 做业名 到达时间 工做时间 # 就绪队列: => Process3->Process9->Process8->Process7->Process2 # 已完成进程队列: => Process6->Process1 # 后备队列: => Job5->Job4 ------------------------------------------------------ 当前系统时间 : 14 # 无做业到达 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process3 1 W Process9 2 R Process8 1 R Process7 1 R Process2 5 R --- 后备队列 --- 做业名 到达时间 工做时间 Job5 8        2 Job4 6        2    

    --- 做业调度表 --- 做业名 到达时间 工做时间 # 进程Process3已完成,退出就绪队列 # 就绪队列: => Process9->Process8->Process7->Process2 # 已完成进程队列: => Process6->Process1->Process3 # 后备队列: => Job5->Job4 ------------------------------------------------------ 当前系统时间 : 15 # 无做业到达 # 将做业Job5投入到就绪队列 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process9 2 W Process8 1 R Process7 1 R Process2 5 R Process5 2 R --- 后备队列 --- 做业名 到达时间 工做时间 Job4 6        2    

    --- 做业调度表 --- 做业名 到达时间 工做时间 # 就绪队列: => Process8->Process7->Process2->Process5->Process9 # 已完成进程队列: => Process6->Process1->Process3 # 后备队列: => Job4 ------------------------------------------------------ 当前系统时间 : 16 # 无做业到达 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process8 1 W Process7 1 R Process2 5 R Process5 2 R Process9 1 R --- 后备队列 --- 做业名 到达时间 工做时间 Job4 6        2    

    --- 做业调度表 --- 做业名 到达时间 工做时间 # 进程Process8已完成,退出就绪队列 # 就绪队列: => Process7->Process2->Process5->Process9 # 已完成进程队列: => Process6->Process1->Process3->Process8 # 后备队列: => Job4 ------------------------------------------------------ 当前系统时间 : 17 # 无做业到达 # 将做业Job4投入到就绪队列 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process7 1 W Process2 5 R Process5 2 R Process9 1 R Process4 2 R --- 后备队列 --- 做业名 到达时间 工做时间 --- 做业调度表 --- 做业名 到达时间 工做时间 # 进程Process7已完成,退出就绪队列 # 就绪队列: => Process2->Process5->Process9->Process4 # 已完成进程队列: => Process6->Process1->Process3->Process8->Process7 # 后备队列: =>------------------------------------------------------ 当前系统时间 : 18 # 无做业到达 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process2 5 W Process5 2 R Process9 1 R Process4 2 R --- 后备队列 --- 做业名 到达时间 工做时间 --- 做业调度表 --- 做业名 到达时间 工做时间 # 就绪队列: => Process5->Process9->Process4->Process2 # 已完成进程队列: => Process6->Process1->Process3->Process8->Process7 # 后备队列: =>------------------------------------------------------ 当前系统时间 : 19 # 无做业到达 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process5 2 W Process9 1 R Process4 2 R Process2 4 R --- 后备队列 --- 做业名 到达时间 工做时间 --- 做业调度表 --- 做业名 到达时间 工做时间 # 就绪队列: => Process9->Process4->Process2->Process5 # 已完成进程队列: => Process6->Process1->Process3->Process8->Process7 # 后备队列: =>------------------------------------------------------ 当前系统时间 : 20 # 无做业到达 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process9 1 W Process4 2 R Process2 4 R Process5 1 R --- 后备队列 --- 做业名 到达时间 工做时间 --- 做业调度表 --- 做业名 到达时间 工做时间 # 进程Process9已完成,退出就绪队列 # 就绪队列: => Process4->Process2->Process5 # 已完成进程队列: => Process6->Process1->Process3->Process8->Process7->Process9 # 后备队列: =>------------------------------------------------------ 当前系统时间 : 21 # 无做业到达 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process4 2 W Process2 4 R Process5 1 R --- 后备队列 --- 做业名 到达时间 工做时间 --- 做业调度表 --- 做业名 到达时间 工做时间 # 就绪队列: => Process2->Process5->Process4 # 已完成进程队列: => Process6->Process1->Process3->Process8->Process7->Process9 # 后备队列: =>------------------------------------------------------ 当前系统时间 : 22 # 无做业到达 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process2 4 W Process5 1 R Process4 1 R --- 后备队列 --- 做业名 到达时间 工做时间 --- 做业调度表 --- 做业名 到达时间 工做时间 # 就绪队列: => Process5->Process4->Process2 # 已完成进程队列: => Process6->Process1->Process3->Process8->Process7->Process9 # 后备队列: =>------------------------------------------------------ 当前系统时间 : 23 # 无做业到达 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process5 1 W Process4 1 R Process2 3 R --- 后备队列 --- 做业名 到达时间 工做时间 --- 做业调度表 --- 做业名 到达时间 工做时间 # 进程Process5已完成,退出就绪队列 # 就绪队列: => Process4->Process2 # 已完成进程队列: => Process6->Process1->Process3->Process8->Process7->Process9->Process5 # 后备队列: =>------------------------------------------------------ 当前系统时间 : 24 # 无做业到达 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process4 1 W Process2 3 R --- 后备队列 --- 做业名 到达时间 工做时间 --- 做业调度表 --- 做业名 到达时间 工做时间 # 进程Process4已完成,退出就绪队列 # 就绪队列: => Process2 # 已完成进程队列: => Process6->Process1->Process3->Process8->Process7->Process9->Process5->Process4 # 后备队列: =>------------------------------------------------------ 当前系统时间 : 25 # 无做业到达 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process2 3 W --- 后备队列 --- 做业名 到达时间 工做时间 --- 做业调度表 --- 做业名 到达时间 工做时间 # 就绪队列: => Process2 # 已完成进程队列: => Process6->Process1->Process3->Process8->Process7->Process9->Process5->Process4 # 后备队列: =>------------------------------------------------------ 当前系统时间 : 26 # 无做业到达 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process2 2 W --- 后备队列 --- 做业名 到达时间 工做时间 --- 做业调度表 --- 做业名 到达时间 工做时间 # 就绪队列: => Process2 # 已完成进程队列: => Process6->Process1->Process3->Process8->Process7->Process9->Process5->Process4 # 后备队列: =>------------------------------------------------------ 当前系统时间 : 27 # 无做业到达 --- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 Process2 1 W --- 后备队列 --- 做业名 到达时间 工做时间 --- 做业调度表 --- 做业名 到达时间 工做时间 # 进程Process2已完成,退出就绪队列 # 就绪队列: => 空 # 已完成进程队列: => Process6->Process1->Process3->Process8->Process7->Process9->Process5->Process4->Process2 # 后备队列: =>------------------------------------------------------ 当前系统时间 : 28

--- 运行队列 & 就绪队列 & 已完成队列 --- 进程名 运行时间 进程状态 --- 后备队列 --- 做业名 到达时间 工做时间 --- 做业调度表 --- 做业名 到达时间 工做时间 # 就绪队列: => 空 # 已完成进程队列: => Process6->Process1->Process3->Process8->Process7->Process9->Process5->Process4->Process2 # 后备队列: =>------------------------------------------------------
View Code

源代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <time.h>
 4 #include <stdlib.h>
 5 #include <string.h>
 6 using namespace std;  7 
 8 #define JOBSUM    9    //进程/做业总数
 9 #define JOBNUM    5    //容许的做业道数
 10 #define PRITOP    3    //最高优先级级数
 11 #define TIMELIMIT 10    //时间限制
 12 
 13 struct Job{    //做业
 14     char jname[40];    //做业名
 15     int start;    //到达时间
 16     int pri;    //优先级
 17     int worktime;    //工做时间
 18     Job *next;    //连接指针
 19 };  20 
 21 struct PCB{  22     PCB* next;  23     char pname[40];    //进程名
 24     int time;    //进程运行时间 
 25     char status;    //运行状态
 26 };  27 
 28 bool CreateJob(Job* jobtable,char name[])    //建立做业,将做业放入做业调度表
 29 {  30     //随机生成一个做业
 31     Job *p = new Job;  32     strcpy(p->jname,name);  33     p->start = rand()%(TIMELIMIT-1)+1;  34     p->worktime = rand()%(TIMELIMIT-p->start)+1;  35     p->pri = rand()%PRITOP;  36     p->next = NULL;  37 
 38     //将做业放入做业调度表
 39     Job* now = jobtable;  40     
 41     //将做业放入做业调度表,按到达时间排序
 42     if(now->next==NULL){    //后备队列仍是空的时候
 43         now->next = p;  44  }  45     else{  46         if(p->start <= now->next->start){    //当新生成的做业工做时间比后备队列第一个做业工做时间就小
 47             p->next = now->next;  48             now->next = p;  49  }  50         else{  51             Job *q = now->next;  52             while( (p->start > q->start) && (q->next!=NULL) ){    //找到插入的位置
 53                 q = q->next;  54  }  55             if( (p->start > q->start) && q->next==NULL){    //新生成的做业的start比后备队列中全部做业的start都大,则排在最后
 56                 q->next = p;  57  }  58             else if(p->start <= q->start){    //找到插入的位置,这个位置的start小于或者等于下一个节点的start
 59                 Job *t = now->next;  60                 while(t->next!=q){  61                     t = t->next;  62  }  63                 t->next = p;  64                 p->next = q;  65  }  66  }  67  }  68 
 69     return true;  70 }  71 
 72 bool AddHoubei(Job *jobtable,Job *p,Job *&jhead)    //将做业p放入后备队列jhead,按短做业优先放置
 73 {  74     //将做业p从做业调度表jobtable中去除
 75     Job* q = jobtable;  76     while(q->next!=p && q->next!=NULL){  77         q = q->next;  78  }  79     if(q->next==p){  80         q->next = p->next;  81         p->next = NULL;  82  }  83 
 84     //将做业p放入后备队列jhead,按短做业优先放置
 85     if(jhead==NULL){    //后备队列仍是空的时候
 86         jhead = p;  87  }  88     else{  89         if(p->worktime <= jhead->worktime){    //当新生成的做业工做时间比后备队列第一个做业工做时间就小
 90             p->next = jhead;  91             jhead = p;  92  }  93         else{  94             Job *q = jhead;  95             while( (p->worktime > q->worktime) && (q->next!=NULL) ){    //找到插入的位置
 96                 q = q->next;  97  }  98             if( (p->worktime > q->worktime) && q->next==NULL){    //新生成的做业的worktime比后备队列中全部做业的worktime都大,则排在最后
 99                 q->next = p; 100  } 101             else if(p->worktime <= q->worktime){    //找到插入的位置,这个位置的worktime小于或者等于下一个节点的worktime
102                 Job *t = jhead; 103                 while(t->next!=q){ 104                     t = t->next; 105  } 106                 t->next = p; 107                 p->next = q; 108  } 109  } 110  } 111     return true; 112 
113 } 114 
115 bool CreateProcess(PCB* &head,PCB* &tail,Job* &jhead)    //建立新进程
116 { 117     PCB* p = new PCB; 118     char JobID = jhead->jname[3]; 119     strcpy(p->pname,"Process");    //进程名 
120     p->pname[7] = JobID; 121     p->pname[8] = '\0'; 122     p->status = 'R';    //就绪状态
123     p->time = jhead->worktime;        //进程工做时间
124 
125     if(tail==NULL){ 126         //就绪队列仍是空的,则第一次赋值
127         head = p; 128         tail = head; 129         tail->next = head; 130  } 131     else{ 132         //就绪队列不为空
133         tail->next = p; 134         tail = p; 135         p->next = head; 136  } 137 
138     return true; 139 } 140 
141 bool Work(PCB* now)    //当前进程执行
142 { 143     now->time--; 144 
145     return true; 146 } 147 
148 bool DropPro(PCB* &head,PCB* &tail,PCB* &chead,PCB* &ctail)    //将队首进程,推出循环就绪队列
149 { 150     PCB* p = head;        //保存头节点
151     head = head->next;    //头结点指向他的下一个节点
152     tail->next = head;    //将就绪队列尾节点直接指向新的头节点
153     p->next = NULL;        //将分离出来的原来的头节点的next设为空NULL
154 
155     if(ctail==NULL){ 156         //已完成进程队列仍是空的,则第一次赋值
157         chead = p; 158         ctail = chead; 159  } 160     else{ 161         //已完成进程队列不为空,则将当前已完成进程放到队列尾部
162         ctail->next = p; 163         ctail = ctail->next; 164  } 165 
166     return true; 167 } 168 
169 bool NextPro(PCB* &head,PCB* &tail)    //当前进程已执行了一个时间片,将其置于循环队列尾端。即将head和tail向前推动一次
170 { 171     head = head->next; 172     tail = tail->next; 173 
174     return true; 175 } 176 
177 
178 void printRQ(PCB* head,int readynum)    //打印当前就绪队列
179 { 180     PCB* p = head; 181     printf("=> "); 182     if(readynum==0){ 183         //就绪队列已空
184         printf("空\n"); 185         return ; 186  } 187     while(p->next!=head){ 188         printf("%s->",p->pname); 189         p = p->next; 190  } 191     printf("%s\n",p->pname); 192 } 193 
194 void printCQ(PCB* chead,PCB* ctail)    //打印当前已完成进程队列
195 { 196     PCB* p = chead; 197     printf("=> "); 198     if(chead==NULL){ 199         //已完成进程队列队列已空
200         printf("空\n"); 201         return ; 202  } 203     while(p!=ctail){ 204         printf("%s->",p->pname); 205         p = p->next; 206  } 207     printf("%s\n",p->pname); 208 } 209 
210 void printJQ(Job* jhead)    //打印当先后备队列
211 { 212     Job* p = jhead; 213     printf("=> "); 214     if(jhead==NULL){ 215         printf("空\n"); 216         return ; 217  } 218     while(p->next!=NULL){ 219         printf("%s->",p->jname); 220         p = p->next; 221  } 222     printf("%s\n",p->jname); 223 } 224 
225 void getJobName(int i,char name[])    //得到当前进程名 
226 { 227     //进程名
228     strcpy(name,"Job"); 229     int len = strlen(name); 230     name[len] = '0'+i; 231     name[len+1] = '\0'; 232 } 233 
234 
235 void printProInfo(PCB* now)    //打印当前进程信息
236 { 237     if(now==NULL){ 238         printf("当前没有进程\n"); 239         return ; 240  } 241     printf("# 当前进程为\n"); 242     printf("进程名:%s\n",now->pname); 243     printf("运行时间:%d\n",now->time); 244     printf("进程状态:%c\n",now->status); 245 } 246 
247 void printAllJobInfo(Job* jhead)    //输出全部做业信息
248 { 249     Job* p = jhead->next; 250     printf("\t--- 做业调度表 ---\n"); 251     printf("做业名\t"); 252     printf("到达时间\t"); 253     printf("工做时间\n"); 254     while(p!=NULL){ 255         printf("%s\t",p->jname); 256         printf("%d\t\t",p->start); 257         printf("%d\n",p->worktime); 258         p = p->next; 259  } 260 } 261 
262 
263 void printQueueInfo(Job *jobtable,Job *jhead,PCB *head,PCB *rhead,PCB *chead,int tablenum,int houbeinum,int readynum)    //打印全部队列信息
264 { 265     printf("\n"); 266     printf("--- 运行队列 & 就绪队列 & 已完成队列 ---\n"); 267     printf("进程名\t\t"); 268     printf("运行时间\t"); 269     printf("进程状态\t"); 270     printf("\n"); 271 
272     PCB *p = NULL; 273     //输出运行队列信息
274     if(readynum!=0){ 275         p = rhead; 276         printf("%s\t",p->pname); 277         printf("%d\t\t",p->time); 278         printf("%c\t",'W'); 279         printf("\n"); 280  } 281 
282     //输出就绪队列信息
283     if(readynum!=0){ 284         p = head->next; 285         while(p!=head){ 286             printf("%s\t",p->pname); 287             printf("%d\t\t",p->time); 288             printf("%c\t",p->status); 289             printf("\n"); 290             p = p->next; 291  } 292  } 293 
294     //输出完成队列
295     if(chead!=NULL){    //完成队列不为空
296         p = chead; 297         while(p!=chead){ 298             printf("%s\t",p->pname); 299             printf("%d\t\t",p->time); 300             printf("%c\t",p->status); 301             printf("\n"); 302             p = p->next; 303  } 304  } 305 
306 
307     printf("\n"); 308     printf("\t--- 后备队列 ---\n"); 309     printf("做业名\t"); 310     printf("到达时间\t"); 311     printf("工做时间\t"); 312     printf("\n"); 313 
314     Job *q; 315     //输出后备队列
316     if(houbeinum!=0){ 317         q = jhead; 318         while(q!=NULL){ 319             printf("%s\t",q->jname); 320             printf("%d\t\t",q->start); 321             printf("%d\t",q->worktime); 322             printf("\n"); 323             q = q->next; 324  } 325  } 326 
327     printf("\n"); 328     printf("\t--- 做业调度表 ---\n"); 329     printf("做业名\t"); 330     printf("到达时间\t"); 331     printf("工做时间\t"); 332     printf("\n"); 333 
334     //输出做业调度表
335     if(tablenum!=0){ 336         q = jobtable->next; 337         while(q!=NULL){ 338             printf("%s\t",q->jname); 339             printf("%d\t\t",q->start); 340             printf("%d\t",q->worktime); 341             printf("\n"); 342             q = q->next; 343  } 344  } 345     printf("\n"); 346 } 347 
348 
349 void printQueueInfo2(PCB *head,PCB *chead,PCB *ctail,Job *jhead,int readynum)    //打印全部队列信息,第二形态,队列式
350 { 351     printf("\n"); 352     printf("# 就绪队列:\n"); 353  printRQ(head,readynum); 354 
355     printf("# 已完成进程队列:\n"); 356  printCQ(chead,ctail); 357 
358     printf("# 后备队列:\n"); 359  printJQ(jhead); 360 
361     printf("------------------------------------------------------\n"); 362 } 363 
364 int main() 365 { 366     PCB *head=NULL,*tail=NULL;    //就绪队列
367     PCB *rhead=NULL;    //运行队列(运行队列中节点数始终<=1)
368     PCB *chead=NULL,*ctail=NULL;    //已完成进程队列
369     Job *jhead=NULL;    //后备队列
370     Job *jobtable = new Job;    //做业调度表
371     jobtable->next = NULL; 372     int i; 373     int tablenum=0;    //做业调度表中做业数量
374     int houbeinum=0;    //后备队列的做业数量
375     int readynum=0;    //就绪队列进程数 376 
377     //将结果输出到日志文件 378     //freopen("ProcessScheduingLog.log","w",stdout); 379 
380     //初始化
381     srand((unsigned)time(0));    //设置种子
382 
383     for(i=1;i<=JOBSUM;i++){        //初始化每个进程 
384         char name[40]; 385         getJobName(i,name);    //得到做业名
386 
387         if(!CreateJob(jobtable,name)){    //随机建立一个新做业,放入做业调度表中,做业调度表中做业是无序的。
388             printf("Error 1!\n");    //出现错误,直接退出
389             return 0; 390  } 391         else{    //建立成功
392             tablenum++; 393  } 394  } 395  
396     //输出全部做业信息
397  printAllJobInfo(jobtable); 398 
399     printf("\n"); 400     printf("# 开始时间片轮转\n"); 401     printf("\n"); 402     printf("------------------------------------------------------\n"); 403 
404     int curtime = 0;    //系统计时域,运行过的时间片个数 405     //时间片轮转进程调度
406     while(readynum!=0 || houbeinum!=0 || tablenum!=0){    //直到就绪队列为空 且 后备队列为空 且 做业调度表为空,退出循环
407         
408         curtime++;    //计时+1
409         printf("当前系统时间 : %d\n",curtime); 410         printf("\n"); 411 
412         //先检查做业调度表,有到达做业,放入后备队列
413         bool isArrive = false; 414         Job* p = jobtable->next; 415         while(p!=NULL){ 416             if(p->start==curtime){    //有做业到达,将做业放入后备队列,并按短做业优先放置
417                 isArrive = true; 418                 Job *t = p->next; 419                 printf("# 将做业%s投入到后备队列\n",p->jname); 420  AddHoubei(jobtable,p,jhead); 421                 houbeinum++;    //后背队列
422                 tablenum--;    //做业调度表
423                 p = t; 424  } 425             else{ 426                 p = p->next; 427  } 428  } 429         if(!isArrive){ 430             printf("# 无做业到达\n"); 431  } 432 
433         //检查就绪队列是否已满。不满,则将后备队列队首放入就绪队列。
434         if(readynum==JOBNUM){    //已满
435  } 436         else{    //未满,从后备队列中将做业放入就绪队列
437             if(houbeinum!=0){    //后备队列不为空
438                 CreateProcess(head,tail,jhead);    //将做业投入到就绪队列
439                 printf("# 将做业%s投入到就绪队列\n",jhead->jname); 440                 jhead = jhead->next;    //指向后备队列下一个做业
441                 readynum++;    //就绪队列
442                 houbeinum--;    //后备队列
443  } 444             //已空就算了
445  } 446 
447         PCB* now = head; 448         if(now!=NULL){    //当前就绪队列不为空时运行进程 449             //将该进程放入运行队列
450             rhead = now; 451             //printf("将当前进程放入运行队列\n");
452 
453             printQueueInfo(jobtable,jhead,head,rhead,chead,tablenum,houbeinum,readynum);    //打印全部队列信息
454 
455             Work(now);    //执行当前进程
456 
457             if(now->time==0){ 458                 now->status = 'C';    //设置进程为已完成状态
459                 printf("# 进程%s已完成,退出就绪队列\n",now->pname); 460                 DropPro(head,tail,chead,ctail);    //推出循环就绪队列
461                 readynum--; 462                 if(readynum==0){ 463                     head = 0; 464                     tail = 0; 465  } 466  } 467             else{ 468                 NextPro(head,tail);    //已完成,将其置于循环队列尾端。即将head和tail向前推动一次
469  } 470 
471  } 472         
473  printQueueInfo2(head,chead,ctail,jhead,readynum); 474 
475  getchar(); 476     
477  } 478     
479     curtime++;    //计时+1
480     printf("当前系统时间 : %d\n",curtime); 481 
482     printQueueInfo(jobtable,jhead,head,rhead,chead,tablenum,houbeinum,readynum);    //打印全部队列信息
483 
484  printQueueInfo2(head,chead,ctail,jhead,readynum); 485 
486     return 0; 487 }

 

Freecode : www.cnblogs.com/yym2013

相关文章
相关标签/搜索