zoukankan      html  css  js  c++  java
  • 操作系统课程:调度算法

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

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

      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 }
  • 相关阅读:
    java中float和double的区别
    常用的排序算法及其适用场景
    高级排序
    LoadRunner 学习笔记(1)性能测试常见术语
    Oracle 常用函数
    oracle 自定义函数
    Oracle 异常处理
    Oracle 包(package)
    CF1332B Composite Coloring(数学)
    CF55D Beautiful(数位dp)
  • 原文地址:https://www.cnblogs.com/firstrate/p/3404721.html
Copyright © 2011-2022 走看看