多级反馈队列调度算法没有实现,其他均已实现,由于自己注释写的较少,所以不是很好的把代码表现出来!
下面附上实现的进程调度的代码:
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 }