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

实验内容:

第一部分:作业调度


作业名


要求运行时间


优先级


到达时间


链接指针

JCB

提示:

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

作业名      ----作业标识

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

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

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

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

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

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

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

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

第二部分:进程调度

(一)优先级调度:


进程名


链接指针


要求运行时间


优先级


进程状态

PCB

提示:

(1)

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

进程名      ----为作业创建进程时起的名称

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

要求运行时间----进程运行的相对时间片时间,由为之创建进程的作业处得到

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

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

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

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

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


进程名


链接指针


要求运行时间


进程状态

PCB

提示:

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

其它如上题

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

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

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

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

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

实现:

  我并没有完全按照实验内容来做。

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

程序流程如下:

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

  2、时间片轮转开始。

  3、检查就绪队列、后备队列、作业调度表是否都为空。如果是,跳到7,程序结束,否则继续执行。

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

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

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

  7、程序结束。

程序中有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
# 后备队列:
=> 空
------------------------------------------------------

源代码:

  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

时间: 2024-10-09 18:21:53

《操作系统》实验之进程调度的相关文章

[操作系统]实验三 进程调度模拟程序

实验三进程调度模拟程序 专业:商软一班   姓名:黄冠锋 学号:201406114134 1.实验目的和要求 1.1. 实验目的 用高级语言完成一个进程调度程序,以加深对进程的概念及进程调度算法的理解. 1.2.实验要求 1.2.1例题:设计一个有 N个进程并发执行的进程调度模拟程序. 进程调度算法:采用最高优先级优先的调度算法(即把处理机分配给优先级最高的进程)和先来先服务(若优先级相同)算法. (1).  每个进程有一个进程控制块(PCB)表示.进程控制块包含如下信息:进程名.优先级.到达时

操作系统实验三进程调度

目的和要求 1.1.           实验目的 用高级语言完成一个进程调度程序,以加深对进程的概念及进程调度算法的理解. 1.2.           实验要求 1.2.1例题:设计一个有 N个进程并发执行的进程调度模拟程序. 进程调度算法:采用最高优先级优先的调度算法(即把处理机分配给优先级最高的进程)和先来先服务(若优先级相同)算法. (1).  每个进程有一个进程控制块(PCB)表示.进程控制块包含如下信息:进程名.优先级.到达时间.需要运行时间.已用CPU时间.进程状态等等. (2)

实验三 进程调度模拟程序--操作系统

实验三 进程调度模拟程序--操作系统 一. 目的和要求 1.1. 实验目的 用高级语言完成一个进程调度程序,以加深对进程的概念及进程调度算法的理解. 1.2. 实验要求 1.2.1例题:设计一个有 N个进程并发执行的进程调度模拟程序. 进程调度算法:采用最高优先级优先的调度算法(即把处理机分配给优先级最高的进程)和先来先服务(若优先级相同)算法. (1). 每个进程有一个进程控制块(PCB)表示.进程控制块包含如下信息:进程名.优先级.到达时间.需要运行时间.已用CPU时间.进程状态等等. (2

操作系统 实验三、进程调度模拟程序

实验三进程调度模拟程序 专业:商软二班   姓名:江志彬 学号:201406114225 1.实验目的和要求 1.1. 实验目的 用高级语言完成一个进程调度程序,以加深对进程的概念及进程调度算法的理解. 1.2.实验要求 1.2.1例题:设计一个有 N个进程并发执行的进程调度模拟程序. 进程调度算法:采用最高优先级优先的调度算法(即把处理机分配给优先级最高的进程)和先来先服务(若优先级相同)算法. (1).  每个进程有一个进程控制块(PCB)表示.进程控制块包含如下信息:进程名.优先级.到达时

【操作系统】实验三 进程调度模拟程序 截止提交时间:2016.5.12

实验三 进程调度模拟程序 1.    目的和要求 1.1.           实验目的 用高级语言完成一个进程调度程序,以加深对进程的概念及进程调度算法的理解. 1.2.           实验要求 1.2.1例题:设计一个有 N个进程并发执行的进程调度模拟程序. 进程调度算法:采用最高优先级优先的调度算法(即把处理机分配给优先级最高的进程)和先来先服务(若优先级相同)算法. (1).  每个进程有一个进程控制块(PCB)表示.进程控制块包含如下信息:进程名.优先级.到达时间.需要运行时间.

12.3 实验三 进程调度模拟程序

  实验三 进程调度模拟程序 13物联网   201306104126  谢秋有 1. 目的和要求 实验目的 用高级语言完成一个进程调度程序,以加深对进程的概念及进程调度算法的理解. 实验要求 设计一个有 N(N不小于5)个进程并发执行的进程调度模拟程序. 进程调度算法:“时间片轮转法”调度算法对N个进程进行调度. 2. 实验内容 完成两个算法(简单时间片轮转法.多级反馈队列调度算法)的设计.编码和调试工作,完成实验报告. 1) 每个进程有一个进程控制块(PCB)表示.进程控制块包含如下信息:进

实验三进程调度模拟程序2.0

实验三进程调度模拟程序2.0 一.实验目的 用高级语言完成一个进程调度程序,以加深对进程的概念及进程调度算法的理解. 二.实验内容和要求 设计一个有 N个进程并发执行的进程调度模拟程序. 1.模拟进程数据的生成 允许用户指定作业的个数(2-24),默认值为5. 允许用户选择输入每个进程的到达时间,所需运行时间,进程的运行时间以时间片为单位. 2. 模拟调度程序的功能 2.1 按照模拟数据的到达时间和所需运行时间,能分别执行以下调度算法. FCFS SJ HRRN RR 2.2 显示每种算法下各进

操作系统实验二(调度算法模拟-先进先出-时间片轮转法-优先服务调度算法)

实验二 进程调度 一.     实验目的 1.       理解进程运行的并发性. 2.       理解处理器的三级调度. 3.       掌握先来先服务的进程调度算法. 4.       掌握短进程优先的进程调度算法. 5.       掌握时间片轮转的进程调度算法. 二.     实验设备 1.     安装windows或者linux操作系统的PC机 2.     C程序编译环境 三.     实验内容 用c语言编程模拟实现至少一个操作系统的常见进程调度算法.常见的进程调度算法有先来先

北航操作系统实验2019:Lab4-1流程梳理

北航操作系统实验2019:Lab4-1流程梳理 前言 操作系统的实验课实在令人头秃.我们需要在两周时间内学习相关知识.读懂指导书.读懂代码.补全代码.处理玄学bug和祖传bug,以及回答令人窒息的思考题.可以说,这门课的要求非常高,就个人感觉,远比计算机组成实验课要难受. 一方面,想要达到细致理解操作系统每个实现细节,非常困难,需要大量时间和经历的投入:但另一方面,如果我们能够理解了操作系统实现的每个细节,我们的水平也会有大幅度的提升.在这里,我记录下本次实验课下我的学习经历,如果有不对的地方,

实验三&#160;进程调度模拟程序

实验三 进程调度模拟程序 专业:物联网工程   姓名:黄淼  学号:201306104145 一. 实验目的和要求 目的: 用高级语言完成一个进程调度程序,以加深对进程的概念及进程调度算法的理解. 实验要求 设计一个有 N(N不小于5)个进程并发执行的进程调度模拟程序. 进程调度算法:“时间片轮转法”调度算法对N个进程进行调度. 二.实验内容 完成两个算法(简单时间片轮转法.多级反馈队列调度算法)的设计.编码和调试工作,完成实验报告. 1) 每个进程有一个进程控制块(PCB)表示.进程控制块包含