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 }
  • 相关阅读:
    MVC ORM 架构
    Kubernetes 第八章 Pod 控制器
    Kubernetes 第七章 Configure Liveness and Readiness Probes
    Kubernetes 第六章 pod 资源对象
    Kubernetes 第五章 YAML
    Kubernetes 核心组件
    Kubernetes 架构原理
    Kubernetes 第四章 kubectl
    Kubernetes 第三章 kubeadm
    yum 配置及yum 源配置
  • 原文地址:https://www.cnblogs.com/firstrate/p/3404721.html
Copyright © 2011-2022 走看看