操作系统课程:调度算法

多级反馈队列调度算法没有实现,其他均已实现,由于自己注释写的较少,所以不是很好的把代码表现出来!

下面附上实现的进程调度的代码:

  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("....
");
 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("
");
 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 :
");
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
", pcbdata[ready[i]].time_start, pcbdata[ready[i]].time_need);
134             printf("The pid running ....
");
135             _sleep(1);
136 
137             printf("Finish 
");
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
", temp, j, k);
142         }
143         printf("pid diaodu over!!
");
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 :
");
152     temp = pcbdata[0].time_start;//此刻时间
153     for(i=0;i<num;++i){
154         printf("%d -> %s
", i+1, pcbdata[i].name);//输出进程的名字
155         printf("start_time = %d, need time = %d
", 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
", temp, j, k);
162         //打印进程结束时间,中转时间,带权中转时间
163     }
164     printf("pid diaodu over !!
");//调度结束
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 : 
");
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
", i+1, pcbdata[i].name);//输出进程名字
188         printf("start_time = %d, need time = %d
", 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
", temp, j, k);
195     }
196     printf("pid diaodu over !!
");
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: 
");
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
", i+1, pcbdata[i].name);
215         printf("start_time = %d, need time = %d
", 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
",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:
The 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
", 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
", 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
", 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:
The 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
", k, pcbdata[pos].name, gap, pcbdata[pos].time_left, pcbdata[pos].time_used);
327             //打印进程的剩余时间,使用时间
328             printf("The now time : %d
", 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
", 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 : 
");
365         printf("1: FCFS
");
366         printf("2: SJF
");
367         printf("3: HRF
");
368         printf("4: Timeslice
");
369         printf("5: MRLA
");
370         printf("0: exit
");
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
");break;
380         }
381     }
382     _keygo();
383     return 0;
384 }
原文地址:https://www.cnblogs.com/firstrate/p/3404721.html