多级反馈队列调度算法没有实现,其他均已实现,由于自己注释写的较少,所以不是很好的把代码表现出来!
下面附上实现的进程调度的代码:
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <
string
.h>
4
#include <time.h>
5
6
#define
maxnum 10
7
#define
getpch(type) (type* malloc(sizeof(type)))
8
typedef
struct
pcb PCB;
9
struct
pcb{
10
int
id;
11
char
name[
10
];
12
int
time_start;
//
到达时间
13
int
time_need;
//
服务时间
14
int
time_left;
//
剩余运行时间
15
int
time_used;
//
已经使用CPU时间
16
char
state;
17
};
18
19
void
_sleep(
int
n){
20
clock_t goal;
21
goal = (clock_t)n * CLOCKS_PER_SEC +
clock();
22
while
(goal >
clock());
23
}
24
25
26
char
_keygo(){
27
char
c;
28
printf(
"
....\n
"
);
29
c =
getchar();
30
return
c;
31
}
32
33
int
time_unit =
2
;
34
//
const int maxnum = 10;
35
int
num =
5
;
36
PCB pcbdata[maxnum] =
{
37
{
1000
,
"
A
"
,
0
,
4
,
4
,
0
,
'
R
'
},
38
{
1001
,
"
B
"
,
1
,
3
,
3
,
0
,
'
R
'
},
39
{
1002
,
"
C
"
,
2
,
5
,
5
,
0
,
'
R
'
},
40
{
1003
,
"
D
"
,
3
,
2
,
2
,
0
,
'
R
'
},
41
{
1004
,
"
E
"
,
4
,
4
,
4
,
0
,
'
R
'
},
42
};
43
//
PCB pcbdata[maxnum] = {
44
//
{1000, "A", 1, 3, 3, 0, 'R'},
45
//
{1001, "B", 1, 2, 2, 0, 'R'},
46
//
{1002, "C", 5, 1, 1, 0, 'R'},
47
//
{1003, "D", 6, 5, 5, 0, 'R'},
48
//
{1004, "E", 6, 4, 4, 0, 'R'},
49
//
};
50
//
PCB pcbdata[maxnum] = {
51
//
{1000, "A", 10, 8, 8, 0, 'R'},
52
//
{1001, "B", 12, 14, 14, 0, 'R'},
53
//
{1002, "C", 14, 4, 4, 0, 'R'},
54
//
{1003, "D", 16, 6, 6, 0, 'R'},
55
//
};
56
//
PCB pcbdata[maxnum] = {
57
//
{1000, "A", 8, 2, 4, 0, 'R'},
58
//
{1001, "B", 8.5, 0.5, 3, 0, 'R'},
59
//
{1002, "C", 9, 5, 0.1, 0, 'R'},
60
//
{1003, "D", 9.5, 0.2, 2, 0, 'R'},
61
//
};
62
int
ready[maxnum];
63
int
order[maxnum];
64
void
input(){
65
int
i;
66
printf(
"
pid number is :
"
);
67
scanf(
"
%d
"
, &
num);
68
for
(i=
0
;i<num;++
i){
69
pcbdata[i].id =
1000
+
i;
70
printf(
"
input %d pid's name :
"
, i+
1
);
71
scanf(
"
%s
"
, pcbdata[i].name);
72
printf(
"
input %d pid's start time:
"
, i+
1
);
73
scanf(
"
%d
"
, &
pcbdata[i].time_start);
74
printf(
"
input %d pid's need time:
"
, i+
1
);
75
scanf(
"
%d
"
, &
pcbdata[i].time_need);
76
pcbdata[i].time_left =
pcbdata[i].time_need;
77
printf(
"
\n
"
);
78
pcbdata[i].time_used =
0
;
79
pcbdata[i].state =
'
R
'
;
80
}
81
}
82
83
void
_swap(
int
A[],
int
a,
int
b){
84
int
tmp;
85
tmp =
A[a];
86
A[a] =
A[b];
87
A[b] =
tmp;
88
}
89
90
void
_swap1(PCB A[],
int
a,
int
b){
91
PCB
92
tmp;
93
tmp =
A[a];
94
A[a] =
A[b];
95
A[b] =
tmp;
96
}
97
98
int
comp (
const
void
*a,
const
void
*
b )
99
{
100
return
(* ( PCB * ) a).time_start - (* ( PCB *
) b).time_start;
101
}
102
103
int
compID (
const
void
*a,
const
void
*
b )
104
{
105
return
(* ( PCB * ) a).id - (* ( PCB *
) b).id;
106
}
107
108
int
compneed (
const
void
*a,
const
void
*
b )
109
{
110
return
(* ( PCB * ) a).time_need - (* ( PCB *
) b).time_need;
111
}
112
113
114
//
老师版本
115
void
FCFS(){
116
int
i, j, temp;
117
double
k;
118
for
(i=
0
;i<num;++
i){
119
order[i] =
pcbdata[i].time_start;
120
ready[i] =
i;
121
}
122
for
(i=
0
;i<num;++
i)
123
for
(j=i+
1
;j<num;++
j){
124
if
(order[i] >
order[j]){
125
_swap(order, i, j);
126
_swap(ready, i, j);
127
}
128
}
129
printf(
"
FCFS :\n
"
);
130
temp = pcbdata[ready[
0
]].time_start;
131
for
(i=
0
;i<num;++
i){
132
printf(
"
%d --> %s,
"
, i+
1
, pcbdata[ready[i]].name);
133
printf(
"
start time -> %d, need time -> %d\n
"
, pcbdata[ready[i]].time_start, pcbdata[ready[i]].time_need);
134
printf(
"
The pid running ....\n
"
);
135
_sleep(
1
);
136
137
printf(
"
Finish \n
"
);
138
temp +=
pcbdata[ready[i]].time_need;
139
j = temp -
pcbdata[ready[i]].time_start;
140
k = (
float
)j /
pcbdata[ready[i]].time_need;
141
printf(
"
The finish time ->%d, the zhouzhuan time ->%d, daiquan -> %.1f\n
"
, temp, j, k);
142
}
143
printf(
"
pid diaodu over!!\n
"
);
144
}
145
146
//
自己手写一个FCFS 快排版本!
147
void
FCFS1(){
148
int
i, j, temp=
0
;
149
double
k;
150
qsort(pcbdata, num,
sizeof
(PCB), comp);
//
对进程进行的到达时间排序
151
printf(
"
FCFS :\n
"
);
152
temp = pcbdata[
0
].time_start;
//
此刻时间
153
for
(i=
0
;i<num;++
i){
154
printf(
"
%d -> %s\n
"
, i+
1
, pcbdata[i].name);
//
输出进程的名字
155
printf(
"
start_time = %d, need time = %d\n
"
, pcbdata[i].time_start, pcbdata[i].time_need);
156
//
输出进程开始时间,服务时间
157
_sleep(
1
);
158
temp+=pcbdata[i].time_need;
//
结束时间
159
j = temp - pcbdata[i].time_start;
//
中转时间
160
k = (
float
)j / pcbdata[i].time_need;
//
带权中转时间
161
printf(
"
The finist_time = %d, The zhongzhuan_time = %d, The daiquanzhongzhuan time = %g\n
"
, temp, j, k);
162
//
打印进程结束时间,中转时间,带权中转时间
163
}
164
printf(
"
pid diaodu over !!\n
"
);
//
调度结束
165
}
166
167
168
void
SJF(){
169
int
i, j, temp;
170
int
mark =
0
;
171
double
k;
172
qsort(pcbdata, num,
sizeof
(PCB), comp);
//
对进程进行到达时间排序
173
printf(
"
SJF : \n
"
);
174
temp = pcbdata[
0
].time_start;
//
此刻时间
175
for
(i=
0
;i<num;++
i){
176
if
(temp < pcbdata[num-
1
].time_start && !mark){
//
此刻时间小于最长到达时间的进程的到达时间
177
for
(j=i+
1
;j<num;++
j)
178
if
(temp<pcbdata[j].time_start){
//
如果此刻时间小于第j个进程的到达时间
179
qsort(pcbdata+i, j-i,
sizeof
(PCB), compneed);
//
对第i+1到第j个进程进行到达服务时间排序
180
break
;
181
}
182
}
183
else
{
184
qsort(pcbdata+i, num-i,
sizeof
(PCB), compneed);
//
对第i+1进程到后面所有进程进行服务时间排序
185
mark =
1
;
//
标记 代表所有进程已经全部到达
186
}
187
printf(
"
%d -> %s\n
"
, i+
1
, pcbdata[i].name);
//
输出进程名字
188
printf(
"
start_time = %d, need time = %d\n
"
, pcbdata[i].time_start, pcbdata[i].time_need);
189
//
输出进程开始时间,服务时间
190
_sleep(
1
);
191
temp+=
pcbdata[i].time_need;
192
j = temp -
pcbdata[i].time_start;
193
k = (
float
)j /
pcbdata[i].time_need;
194
printf(
"
The finist_time = %d, The zhongzhuan_time = %d, The daiquanzhongzhuan time = %g\n
"
, temp, j, k);
195
}
196
printf(
"
pid diaodu over !!\n
"
);
197
198
}
199
200
void
HRF(){
201
int
i, j, jj, temp, pos, mark;
202
double
k;
203
mark =
0
;
204
float
w[
10
], max;
205
qsort(pcbdata, num,
sizeof
(PCB), comp);
//
对进程进行到达时间排序
206
printf(
"
HRF: \n
"
);
207
temp = pcbdata[
0
].time_start;
//
此刻时间
208
for
(i=
0
;i<num;++
i){
209
if
(i!=
0
&& i!=
pos){
210
mark =
0
;
211
_swap1(pcbdata, i, pos);
//
交换第i个进程和高响应比进程的位置
212
qsort(pcbdata+i, pos-i,
sizeof
(PCB), comp);
//
对除了选中的高响应比进程外其他进程进行到达时间排序
213
}
214
printf(
"
%d -> %s\n
"
, i+
1
, pcbdata[i].name);
215
printf(
"
start_time = %d, need time = %d\n
"
, pcbdata[i].time_start, pcbdata[i].time_need);
216
_sleep(
1
);
217
temp+=
pcbdata[i].time_need;
218
jj = temp -
pcbdata[i].time_start;
219
k = (
float
)jj /
pcbdata[i].time_need;
220
max =
0
;
221
for
(j=i+
1
;j<num;++
j){
222
if
(temp > pcbdata[j].time_start){
//
如果现在时间大于到达时间
223
w[j] = temp - pcbdata[j].time_start + pcbdata[j].time_need;
//
算出第j个进程的优先权
224
w[j] /= pcbdata[j].time_need;
//
算优先权
225
printf(
"
w[%d] = %g
"
,j, w[j]);
//
输出到达进程的所有进程的优先权值
226
if
(w[j] > max) {
//
计算最大优先权值的进程
227
max =
w[j];
228
pos = j;
//
pos 为最大优先权值进程的数组标记
229
}
230
mark =
1
;
231
}
232
}
233
printf(
"
The finist_time = %d, The zhongzhuan_time = %d, The daiquanzhongzhuan time = %g, next weight = %g\n
"
,temp, jj, k, max);
234
//
输出进程结束时间,中转时间,带权中转时间,下一个优先权。
235
}
236
}
237
238
//
这是之前按照第一次老师讲解的方法所编写,由于第一次理论不是按进程执行后插到就绪队列末尾的方法,所以结果只是和老师之前有错的PPT 结果相同。
239
void
_Timeslice(){
240
int
i, j, temp, mark, gap, n, k;
241
float
kk;
242
qsort(pcbdata, num,
sizeof
(PCB), comp);
243
mark = k =
0
;
244
temp = pcbdata[
0
].time_start;
245
printf(
"
Timeslice:\nThe gap is :
"
);
246
scanf(
"
%d
"
, &
n);
247
int
vis[maxnum];
248
memset(vis,
0
,
sizeof
(vis));
249
while
(
1
){
250
for
(i=
0
;i<num;++
i){
251
if
(pcbdata[i].state ==
'
E
'
)
continue
;
252
if
(temp <= pcbdata[i].time_start && i!=
0
) i =
0
;
253
printf(
"
temp : %d\n
"
, temp);
254
++
k;
255
gap =
n;
256
if
(pcbdata[i].time_left >=
gap)
257
pcbdata[i].time_left -=
gap;
258
else
if
(pcbdata[i].time_left >
0
&& pcbdata[i].time_left <
gap){
259
gap =
pcbdata[i].time_left;
260
pcbdata[i].time_left =
0
;
261
}
262
temp +=
gap;
263
pcbdata[i].time_used = pcbdata[i].time_need -
pcbdata[i].time_left;
264
printf(
"
%d -> %s, the gap : %d, the time_left: %d, the time_used : %d\n
"
, k, pcbdata[i].name, gap, pcbdata[i].time_left, pcbdata[i].time_used);
265
if
(pcbdata[i].time_left ==
0
){
266
pcbdata[i].state =
'
E
'
;
267
vis[i] =
1
;
268
j = temp -
pcbdata[i].time_start;
269
kk = (
float
)j /
pcbdata[i].time_need;
270
printf(
"
The %s's state: %c ,The finist_time = %d, The zhongzhuan_time = %d, The daiquanzhongzhuan time = %g\n
"
, pcbdata[i].name, pcbdata[i].state, temp, j, kk);
271
}
272
_sleep(
1
);
273
}
274
for
(i=
0
;i<num;++
i){
275
if
(vis[i] ==
1
) mark =
1
;
276
else
{ mark =
0
;
break
;}
277
}
278
if
(mark ==
1
)
break
;
279
}
280
}
281
282
//
改进过的时间片轮转,按照第二次老师上课讲解的做法所编写,由于要维护动态就绪队列,所以用链表来模拟就绪队列。
283
typedef
struct
node *
link;
284
typedef
struct
node {
int
data; link next;} Node;
285
//
创建链表来模拟就绪队列
286
void
insert(
int
data, link L){
//
尾插法插入元素
287
link y = malloc(
sizeof
(Node));
288
link p =
L;
289
while
(p->next) p = p->
next;
290
y->data =
data;
291
y->next = p->
next;
292
p->next =
y;
293
}
294
295
void
delete(link L){
//
从链表头部删除元素
296
L->next = L->next->
next;
297
}
298
void
Timeslice(){
299
int
i, j, temp, mark, gap, n, k, pos;
300
float
kk;
301
int
vis[maxnum];
302
memset(vis,
0
,
sizeof
(vis));
303
link L = malloc(
sizeof
*
L);
304
L->next =
0
;
305
k =
0
;
306
qsort(pcbdata, num,
sizeof
(PCB), comp);
//
对进程进行到达时间排序
307
temp = pcbdata[
0
].time_start;
308
printf(
"
Timeslice:\nThe gap is :
"
);
309
scanf(
"
%d
"
, &n);
//
输入时间片的长短
310
insert(
0
, L);
311
vis[
0
] =
1
;
312
while
(
1
){
313
++
k;
314
gap =
n;
315
if
(L->next){
//
如果链表有元素
316
pos = L->next->data;
//
pos 为链表的首元素
317
if
(pcbdata[pos].time_left >= gap)
//
如果剩余时间大于时间片长度,就用剩余时间减去时间片长度
318
pcbdata[pos].time_left -=
gap;
319
else
if
(pcbdata[pos].time_left >
0
&& pcbdata[pos].time_left <
gap){
320
//
如果剩余时间不大于时间片长度,则剩余时间为0,此刻的时间片长度等于剩余时间
321
gap =
pcbdata[pos].time_left;
322
pcbdata[pos].time_left =
0
;
323
}
324
temp +=
gap;
325
pcbdata[pos].time_used = pcbdata[pos].time_need - pcbdata[pos].time_left;
//
求CPU进程是用时间
326
printf(
"
%d -> %s, the gap : %d, the time_left: %d, the time_used : %d\n
"
, k, pcbdata[pos].name, gap, pcbdata[pos].time_left, pcbdata[pos].time_used);
327
//
打印进程的剩余时间,使用时间
328
printf(
"
The now time : %d\n
"
, temp);
329
//
打印此刻时间
330
if
(pcbdata[pos].time_left ==
0
){
//
如果剩余时间为0,把进程状态从'R'改成‘E’
331
pcbdata[pos].state =
'
E
'
;
332
j = temp -
pcbdata[pos].time_start;
333
kk = (
float
)j /
pcbdata[pos].time_need;
334
printf(
"
The %s's state: %c ,The finist_time = %d, The zhongzhuan_time = %d, The daiquanzhongzhuan time = %g\n
"
, pcbdata[pos].name, pcbdata[pos].state, temp, j, kk);
335
}
336
_sleep(
1
);
337
}
338
else
break
;
339
340
delete(L);
//
删除链表第一个元素,相当于维护就绪队列
341
for
(i=
0
;i<num;++
i){
342
if
(vis[i])
continue
;
343
if
(!vis[i] && pcbdata[i].time_start<=
temp){
344
insert(i, L);
345
vis[i] =
1
;
346
}
347
}
348
if
(pcbdata[pos].time_left >
0
)
//
刚才执行过的进程插到就绪队列末尾
349
insert(pos, L);
350
}
351
}
352
353
354
355
void
MRLA(){}
356
357
int
main(
int
argc,
char
const
*
argv[])
358
{
359
int
i =
0
;
360
int
sch =
99
;
361
//
input();
362
while
(sch !=
0
){
363
qsort(pcbdata, num,
sizeof
(PCB), compID);
//
刚开始按进程ID顺序排序
364
printf(
"
Please choose one diaodu : \n
"
);
365
printf(
"
1: FCFS\n
"
);
366
printf(
"
2: SJF\n
"
);
367
printf(
"
3: HRF\n
"
);
368
printf(
"
4: Timeslice\n
"
);
369
printf(
"
5: MRLA\n
"
);
370
printf(
"
0: exit\n
"
);
371
printf(
"
Please input a number :
"
);
372
scanf(
"
%d
"
, &
sch);
373
switch
(sch){
374
case
1
: FCFS();
break
;
375
case
2
: SJF();
break
;
376
case
3
: HRF();
break
;
377
case
4
: Timeslice();
break
;
378
case
5
: MRLA();
break
;
379
case
0
: printf(
"
exit the programe\n
"
);
break
;
380
}
381
}
382
_keygo();
383
return
0
;
384
}

