前言

时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法,又称RR调度。每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。

更多介绍请看-> 时间片轮转_百度百科

自己用C简单实现了一下模拟时间片轮换,列队采用单向链表,在PCB释放上稍显啰嗦,如果用双向链表或者改用C++的vector容器的话代码会清晰很多。

代码

应该没什么奇怪的Bug了(确信

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <stdio.h>
#include <stdlib.h>

typedef enum pstate
{
READY,
RUNNING,
FINISHED
} pstate;

typedef struct PCB
{
// 进程号
int pid;
// 进程状态
pstate state;
// 到达时间
int arrivetime;
// 还需要运行时间
int runtime;
// 优先级
int prior;
// 下一个PCB指针
struct PCB *next;
} PCB;

int main()
{
srand(20);
// 时间片
int pian = 3;
// 进程数量
int p_num = 5;
// 初始化进程列队
int pid_count = 1;
PCB *head = (PCB *)malloc(sizeof(PCB));
head->pid = -1;
head->prior = -1;
head->next = NULL;
PCB *current = head;
while (p_num > 0)
{
PCB *new_pcb = (PCB *)malloc(sizeof(PCB));

new_pcb->pid = pid_count;
pid_count++;
new_pcb->state = READY;
new_pcb->arrivetime = rand() % 20;
new_pcb->runtime = rand() % 10 + 1;
new_pcb->prior = rand() % 10 + 1;
new_pcb->next = NULL;

current->next = new_pcb;
current = current->next;
p_num--;
}

// 开始
int now_time = 0;
while (1)
{
PCB *ahead_current = head;
current = head->next;
// 当列队中所有pcb已执行完毕
if (current == NULL)
{
break;
}

// 获取已到达的优先级最高的进程
PCB *ahead_pcb = NULL;
PCB *max_prior_pcb = head;
while (current != NULL)
{
if (current->arrivetime <= now_time && current->state == READY && current->prior >= max_prior_pcb->prior)
{
max_prior_pcb = current;
ahead_pcb = ahead_current;
}
ahead_current = current;
current = current->next;
}

// 当列队中均等待
if (max_prior_pcb->pid < 0)
{
printf("当前时间为:%d 等待程序到达中……\n",now_time);
now_time += 1;
continue;
}

// 开始执行
// 切换PCB状态
max_prior_pcb->state = RUNNING;
printf("当前执行程序:PID:%d 到达时间:%d 剩余时间:%d 优先级:%d\n", max_prior_pcb->pid, max_prior_pcb->arrivetime, max_prior_pcb->runtime, max_prior_pcb->prior);
// 判断时间片内是否执行完
if (max_prior_pcb->runtime <= pian)
{
// 当前时间增加
now_time += max_prior_pcb->runtime;
// pcb剩余时间归零
max_prior_pcb->runtime = 0;
// pcb状态完成
max_prior_pcb->state = FINISHED;
printf("当前程序执行完成:PID:%d 剩余时间:%d 状态:已完成 当前时间:%d\n\n", max_prior_pcb->pid, max_prior_pcb->runtime,now_time);
// 移出列队
ahead_pcb->next = max_prior_pcb->next;
free(max_prior_pcb);
}
else
{
// 当前时间增加
now_time += pian;
// 计算pcb剩余时间
max_prior_pcb->runtime = (max_prior_pcb->runtime - pian);
// pcb状态就绪
max_prior_pcb->state = READY;
printf("当前程序时间片已耗费完:PID:%d 剩余时间:%d 状态:等待继续 当前时间:%d\n\n", max_prior_pcb->pid, max_prior_pcb->runtime,now_time);
}
}
printf("所有程序已执行完毕:花费时间:%d\n", now_time);
}