0%

进程调度(下)

实验目的

  • 针对作业调度问题,能够分析影响作业调度性能的主要因素,通过设计最优的方案实现作业调度算法
  • 针对不同作业的要求,选择不同的调度算法,满足不同作业,尤其短作业运行的需求

实验原理

先来先服务调度算法:

按作业提交的/到达的(到达后备队列的时间)先后次序从外存后备队列中选择几个最先进入该队列的作业为他们分配资源、创建进程,然后再放入就绪队列。

每个作业由一个作业控制块JCB表示,JCB可以包含如下信息:作业名、提交时间、所需的运行时间、作业状态等等。
作业的状态可以是等待W(Wait)、运行R(Run)和完成F(Finish)三种状态之一。每个作业的最初状态总是等待W。 各个等待的作业按照提交时刻的先后次序排队。

每个作业完成后要输出该作业的开始运行时刻、完成时刻、周转时间和带权周转时间,这一组作业完成后计算并输出这组作业的平均周转时间、平均带权周转时间。

短作业优先调度算法;

根据作业的估计运行时间的长短,从外存后备队列中选择若干个作业为他们分配资源、创建进程,然后再放入就绪队列。

每个作业由一个作业控制块JCB表示,JCB可以包含如下信息:作业名、提交时间、所需的运行时间、作业状态等等。

作业的状态可以是等待W(Wait)、运行R(Run)和完成F(Finish)三种状态之一。每个作业的最初状态总是等待W。 各个等待的作业按照提交时刻的先后次序排队。

每个作业完成后要输出该作业的开始运行时刻、完成时刻、周转时间和带权周转时间,这一组作业完成后计算并输出这组作业的平均周转时间、平均带权周转时间。

实验内容

大部分代码与进程调度(上)相同,只需添加和修改部分代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
PCB* Getshort(struct ReadyQueue rq) {
PCB* p = rq.head; PCB* p1 = rq.head;
while (p) {
if (p->needtime < p1->needtime)p1 = p;
p = p->next;
}
return p1;
}
void FCFS(struct ReadyQueue rq, ReadyQueue* rq1, struct ReadyQueue* rq2) {
int i = 0;
PCB* p = rq.head;
while (rq1->head != NULL || p) {
if (!rq1->head) i = p->arrivetime;
if (p)Processin(&p, rq1, i);
PCB* p1 = rq1->head;
while (p1->needtime) {
p1->state = 'R';
printf("第%d个时刻\n", i);
Print(*rq1);
printf("******************************\n");
i++;
p1->servicetime += 1;
p1->state = 'W';
if (p)Processin(&p, rq1, i);
p1->needtime -= 1;
}
p1->finishtime = i;
p1->state = 'F';
Delete(rq1, p1); EnQueue(rq2, p1);
}
}
void SJF(struct ReadyQueue rq, ReadyQueue* rq1, struct ReadyQueue* rq2) {
int i = 0;
PCB* p = rq.head;
while (rq1->head != NULL || p) {
if (!rq1->head) i = p->arrivetime;
if (p)Processin(&p, rq1, i);
PCB* p1 = Getshort(*rq1);
while (p1->needtime) {
p1->state = 'R';
printf("第%d个时刻\n", i);
Print(*rq1);
printf("******************************\n");
i++;
p1->servicetime += 1;
p1->state = 'W';
if (p)Processin(&p, rq1, i);
p1->needtime -= 1;
}
p1->finishtime = i;
p1->state = 'F';
Delete(rq1, p1); EnQueue(rq2, p1);
}
}
int main()
{
ReadyQueue rq, rq2; ReadyQueue rq1; initQueue(&rq1);
initQueue(&rq); initQueue(&rq2);
int n1, n2;
//scanf("%d%d", &n1, &n2);
scanf("%d", &n1);
Creat(n1, &rq);
//NonPreemptive(rq, &rq1, &rq2);
//RR(n2, rq, &rq1, &rq2);
//FCFS(rq, &rq1, &rq2);
SJF(rq, &rq1, &rq2);
Show(rq2);
}

先来先服务演示

alt text
alt text

短作业优先演示

alt text
alt text

实验总结

通过实验,我们可以观察到这两种算法在不同情况下的表现。例如,对于长作业和短作业混合的工作负载,SJF通常会提供更好的服务时间,因为它首先调度短作业。然而,如果所有作业的长度都相同,那么FCFS和SJF的性能就会相同。