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