西南交通大学【操作系统实验3】

实验目的

  1. 掌握进程调度的概念。
  2. 通过学习Linux内核源码编写风格,重点理解进程调度策略算法,包括FCFS、 RR、SRT、Feedback的调度算法。

实验内容

本实验要求在Linux的用户态下编程实现进程调度策略算法的模拟程序

A.验证test4.c:

  1. 1.FCFS(先到先服务)
  2. 2.RR(轮循)

B.新建工程schedule,实现

  1. 3.SRT(最短进程优先)
  2. 4.Feedback(最短剩余时间)

实验环境

Ubuntu 12.04 LTS

Device name: oslinux-virtual-machine

Memory: 1001.2MiB

Processor: AMD Ryzen 77730U with Radeon Graphics

Graphics: Unknown

OS type: 32-bit

Disk: 20.3GB

实验步骤

  1. 1. 验证test4.c,理解FIFO和RR两种算法。
  2. 2. 编写SRT和Feedback两种算法,测试运行结果,编写实验报告。

5.实验结果

实验一结果

实验二结果

核心代码

/***************进程调度实验**************/

/*****************************************

采用的是linux0.12的内核编写风格,可参考赵炯的《Linux内核完全剖析》

Author.gdong.guan

版权所有,仅供学习,不要发布到网上

******************************************/

#include<stdio.h>

#include<sys/time.h>

#include<malloc.h>

#include<stdlib.h>



#define  NR_TASKS             64   //系统支持的进程个数

#define  TASK_RUNNING          0   //就绪态

#define  TASK_UNINTERRUPTIBLE  2   //不可中断的睡眠状态

#define  TASK_ZOMBIE           3   //僵死态



//进程表项

struct task_struct{

    long pid;        //进程号

    long state;      //进程运行状态

    long priority;   //优先数

    long counter;    //进程剩余时间片

    long start_time;  //进程开始时间

    long excute_time; //进程执行时间

    long flag;

};



struct task_struct init_task = {

    .pid = 0,

    .state = 0,

    .priority = 0,

    .counter = 0,

    .start_time = 0,

    .excute_time = 0,

    .flag = -1

};



struct task_struct *current = &init_task;

unsigned long volatile jiffies = 0; //系统滴答数

struct task_struct* task[NR_TASKS] = {&init_task,}; //进程指针数组

#define  FIRST_TASK    task[0]

#define  LAST_TASK     task[NR_TASKS-1]



struct run_q {       //进程就绪队列

    struct task_struct *data;

    struct run_q *next;

};

struct run_q *head=NULL,*end=NULL,*r_temp;



#define  N_PROCESS             5   //进程个数

#define  MAX_RUNTIME         100   //最长运行时间

int process[N_PROCESS][2]={{0,3},{2,6},{4,4},{6,5},{8,2}};//进程初始值

int totalExcuteTime = 0;             //cpu总的运行时间

int runState[N_PROCESS][MAX_RUNTIME] = {0};  //进程运行状态的记录



void checkProcessCome();  //判断是否有进程到达,如果有则创建进程

void pause();             //0号进程的运行体

void schedule_f();        //FCFS调度程序

void schedule_s();        //RR调度程序

void switch_to(int pid);  //进程切换

void init();              //基于优先级调度器的初始化

void run(int pid);        //普通进程的运行体

void myfork(int pid);     //进程创建

void delete(int pid);     //进程清除



typedef void funtype(void);

funtype *schedule = NULL;



int main(int argc,char **argv)

{

    int i,j;

    int choice;

    while(1){

        printf("please choice the schedule measure:\n");

        printf("s : SRT策略\n");

        printf("f : Feedback策略\n");

        printf("q : 退出\n");

        printf("choice = ");

        choice = getchar();

        if(choice == '\n')

            choice = getchar();

        switch(choice){

            case 's': schedule = schedule_s;break;

            case 'f': schedule = schedule_f;break;

            case 'q': return 0;

            default : {

                schedule = NULL;

                printf("please input the true symbol(q or s or f)!\n\n");

                continue;

            }

        }

        printf("task id   start  excute\n");

        for(i=0;i<N_PROCESS;i++){

            printf("task %2d: %6d %6d\n",i+1,process[i][0],process[i][1]);

            totalExcuteTime+=process[i][1];

        }

        init();



        //打印进程调度情况

        printf("time   : 0%*c%d\n",totalExcuteTime-2,' ',totalExcuteTime);

        for(i=0;i<N_PROCESS;i++){

            printf("task %2d: ",i+1);

            for(j=0;j<totalExcuteTime;j++){

                if(runState[i][j]==1) printf("#");

                else printf(" ");

                runState[i][j] = 0;

            }

            printf("\n");

        }

        while((head!=NULL)&&(head!=end)){

            r_temp = head;

            head = head->next;

            free(r_temp);

        }

        if(head){

            free(head);

            head = NULL;

            end = NULL;

        }

        current = &init_task;

        jiffies = 0;

        totalExcuteTime = 0;

        printf("\n");

    }

    return 0;

}



int last_mission = -1;

void schedule_f(){

    if(last_mission != -1){

        if(task[last_mission]->state != TASK_ZOMBIE && task[last_mission]->flag != 0){

            task[last_mission]->flag--;

            switch_to(last_mission);

            return;

        }

        if(task[last_mission]->flag != 0){

            if(task[last_mission]->state == TASK_ZOMBIE){

                printf("CHECK\n");

            }

        }

    }

    float index;

    int sum = 0, i, sub;

    for(i = 1;task[i];++i){

        sum += process[i-1][1] - task[i]->excute_time;

    }

    index = (float)(sum) / (float)(i);

    int next = 0;

    if(current->state != TASK_RUNNING){

        r_temp = head;

        if(head == end){

            head = NULL;

            end = NULL;

        }else{

            head = head->next;

            end->next = head;

        }

        free(r_temp);

    }else if(head){

        head = head->next;

        end = end->next;

    }

    for(i = 1;task[i];++i){

        if(task[i]->pid == head->data->pid){

            sub = i;

            break;

        }

    }

    if(process[sub-1][1] - head->data->excute_time > index){

        head->data->flag = 2;

    }else{

        head->data->flag = 1;

    }

    if(head){

        next = head->data->pid;

    }

    last_mission = sub;

    head->data->flag--;

    switch_to(next);

}



void schedule_s(){

    int sub = 0, min_time = MAX_RUNTIME, i;

    for(i = 1;task[i];++i){

        int remain_exe_time;

        remain_exe_time = process[i-1][1] - task[i]->excute_time;

        if(remain_exe_time <= min_time && remain_exe_time != 0){

            sub = i;

            min_time = remain_exe_time;

        }

    }

    if(sub == 0){

        printf("No Process!!!\n");

    }

    switch_to(task[sub]->pid);

}



void switch_to(int pid){

    if(pid)

        run(pid);

    else

        pause();

}



void myfork(int pid){

    struct timeval now;

    struct run_q *p;

    task[pid] = (struct task_struct*)malloc(sizeof(struct task_struct));

    task[pid]->state = TASK_UNINTERRUPTIBLE;

    task[pid]->pid = pid;

    gettimeofday(&now,0);

    srand(now.tv_usec);

    task[pid]->priority = 2 + (int)(4.0f*rand()/(RAND_MAX+1.0f));

    task[pid]->counter = task[pid]->priority;

    task[pid]->start_time = jiffies;

    task[pid]->excute_time = 0;

    task[pid]->state = TASK_RUNNING;



    p = (struct run_q*)malloc(sizeof(struct run_q));

    p->data = task[pid];

    if(head==NULL){

        head = end = p;

        head->next = end;

        end->next = head;

    }else{

        end->next = p;

        end = p;

        end->next = head;

    }

}



void delete(int pid){

    free(task[pid]);

}



void checkProcessCome(){

    int i;

    for(i=0;i<N_PROCESS;i++){

    if(process[i][0]==jiffies)

        myfork(i+1);

    }

}



void init(){

    int i;

    for(i=1;i<NR_TASKS;i++){

        task[i] = NULL;

    }

    checkProcessCome();

    schedule();

}



void pause(){

    current = task[0];

    jiffies++;

    totalExcuteTime++;

    checkProcessCome();

    schedule();

}



void run(int pid){

    int i;

    current = task[pid];

    runState[pid-1][jiffies] = 1;

    jiffies++;

    task[pid]->counter--;

    task[pid]->excute_time++;

    //判断进程是否运行完,如果是则将进程杀死

    if(task[pid]->excute_time==process[pid-1][1]){

        task[pid]->state = TASK_ZOMBIE;

    }

    //判断所有进程是否都运行完,如果是则结束

    if(jiffies>=totalExcuteTime) return;

    checkProcessCome();

    schedule();

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

还有糕手

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值