西南交通大学操作系统实验三——进程调度实验

实验目的

撑握进程调度的概念 学习Linux内核源码编写风格

重点理解进程调度策略算法,包括FCFS、RR、SRT、Feedback的调度算法。


实验内容:

验证test4.c,

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


本文仅提供实验内容2的代码,并且本文代码在test4.c代码文件之上添加内容来实现实验内容2。代码未整理,可能有些凌乱。

/***************进程调度实验**************/
/*****************************************
采用的是linux0.12的内核编写风格,可参考赵炯的《Linux内核完全剖析》
Author.gdong.guan
版权所有,仅供学习,不要发布到网上
******************************************/
#include<cstdio>
#include<sys/time.h>
#include<malloc.h>
#include<cstdlib>

#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 = nullptr, *end = nullptr, *r_temp;

#define  N_PROCESS             5   //进程个数
#define  MAX_RUNTIME         100   //最长运行时间
int process[N_PROCESS][2] = {{0, 20},
                             {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_r();        //RR调度程序
void schedule_s();
void schedule_b();
void switch_to(int pid);  //进程切换
void init();              //基于优先级调度器的初始化
void run(int pid);        //普通进程的运行体
void myfork(int pid);     //进程创建
void mydelete(int pid);     //进程清除

typedef void funtype();

funtype *schedule = nullptr;

int main(int argc, char **argv) {
    int i, j;
    int choice;
    while (true) {
        printf("please choice the schedule measure:\n");
        printf("f : 先到先服务的调度策略\n");
        printf("r : 轮循的调度策略\n");
        printf("s : 最短剩余时间策略\n");
        printf("b : 反馈策略\n");
        printf("q : 退出\n");
        printf("choice = ");
        choice = getchar();
        if (choice == '\n')
            choice = getchar();
        switch (choice) {
            case 'f':
                schedule = schedule_f;
                break;
            case 'r':
                schedule = schedule_r;
                break;
            case 's':
                schedule = schedule_s;
                break;
            case 'b':
                schedule = schedule_b;
                break;
            case 'q':
                return 0;
            default : {
                schedule = nullptr;
                printf("please input the true symbol(b or f or s or or r or q)!\n\n");
                continue;
            }
        }
        printf("task id   Start  Service time\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("Scheduling result\n");
        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 != nullptr) && (head != end)) {
            r_temp = head;
            head = head->next;
            free(r_temp);
        }
        if (head) {
            free(head);
            head = nullptr;
            end = nullptr;
        }
        current = &init_task;
        jiffies = 0;
        totalExcuteTime = 0;
        printf("\n");
    }
    return 0;
}

void schedule_f() {
    int i, next, c;
    struct task_struct **p;
    c = 9999;
    next = 0;
    i = NR_TASKS;
    p = &task[NR_TASKS];
    while (--i) {
        if (!*--p)
            continue;
        if ((*p)->state == TASK_RUNNING && (*p)->start_time < c)
            c = (*p)->start_time, next = i;
    }
    switch_to(next);
}

void schedule_r() {
    int next;
    next = 0;
    if (current->state != TASK_RUNNING) {
        r_temp = head;
        if (head == end) {
            head = nullptr;
            end = nullptr;
        } else {
            head = head->next;
            end->next = head;
        }
        free(r_temp);
    } else if (head) {
        head = head->next;
        end = end->next;
    }
    if (head) next = head->data->pid;
    switch_to(next);
}

void schedule_s() {
    int sub = 0, min_time = MAX_RUNTIME;
    for (int 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!");
    }
    switch_to(task[sub]->pid);
}

int last_mission = -1;

void schedule_b() {
    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");
            }
        }
    }
    float index;
    int sum = 0, i, sub;
    for (i = 1; task[i]; i++) {
        sum += process[i - 1][1] - task[i]->excute_time;
    }
    index = static_cast<float>(sum) / static_cast<float>(i);
    int next;
    next = 0;
    if (current->state != TASK_RUNNING) {
        r_temp = head;
        if (head == end) {
            head = nullptr;
            end = nullptr;
        } 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 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, nullptr);
    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 == nullptr) {
        head = end = p;
        head->next = end;
        end->next = head;
    } else {
        end->next = p;
        end = p;
        end->next = head;
    }
}

void mydelete(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] = nullptr;
    }
    checkProcessCome();
    schedule();
}

void pause() {
    current = task[0];
    //printf("running task %d\n",pid);
    //usleep(1000000);
    jiffies++;
    totalExcuteTime++;
    checkProcessCome();
    schedule();
}

void run(int pid) {
    int i;
    current = task[pid];
    runState[pid - 1][jiffies] = 1;
    //printf("running task %d\n",pid);
    //usleep(1000000);
    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();
}


如有错误请指正。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,进程调度算法是操作系统中非常重要的一部分。常见的进程调度算法有先来先服务(FCFS)、短作业优先(SJF)、高响应比优先(HRRN)、时间片轮转(RR)等。下面是这些算法的 Python 实现: 1. 先来先服务(FCFS): ```python def FCFS(processes): waiting_time = 0 turn_around_time = 0 completion_time = 0 for process in processes: completion_time += process['burst_time'] turn_around_time += completion_time - process['arrival_time'] waiting_time += turn_around_time - process['burst_time'] return waiting_time / len(processes), turn_around_time / len(processes) ``` 2. 短作业优先(SJF): ```python def SJF(processes): processes = sorted(processes, key=lambda x: x['burst_time']) waiting_time = 0 turn_around_time = 0 completion_time = 0 for process in processes: completion_time += process['burst_time'] turn_around_time += completion_time - process['arrival_time'] waiting_time += turn_around_time - process['burst_time'] return waiting_time / len(processes), turn_around_time / len(processes) ``` 3. 高响应比优先(HRRN): ```python def HRRN(processes): waiting_time = 0 turn_around_time = 0 completion_time = 0 for i, process in enumerate(processes): if i == 0: completion_time = process['burst_time'] else: response_ratio_list = [] for j in range(i): response_ratio = (completion_time - processes[j]['arrival_time'] + processes[j]['burst_time']) / processes[j]['burst_time'] response_ratio_list.append(response_ratio) max_response_ratio_index = response_ratio_list.index(max(response_ratio_list)) selected_process = processes.pop(max_response_ratio_index) completion_time += selected_process['burst_time'] turn_around_time += completion_time - selected_process['arrival_time'] waiting_time += turn_around_time - selected_process['burst_time'] return waiting_time / len(processes), turn_around_time / len(processes) ``` 4. 时间片轮转(RR): ```python def RR(processes, time_slice): waiting_time = 0 turn_around_time = 0 completion_time = 0 while processes: for i in range(len(processes)): if processes[i]['burst_time'] > time_slice: completion_time += time_slice processes[i]['burst_time'] -= time_slice else: completion_time += processes[i]['burst_time'] turn_around_time += completion_time - processes[i]['arrival_time'] waiting_time += turn_around_time - processes[i]['burst_time'] processes.pop(i) break return waiting_time / len(processes), turn_around_time / len(processes) ``` 这里的 `processes` 是一个列表,其中每个元素是一个字典,表示一个进程的信息,如下所示: ```python processes = [ {'name': 'P1', 'arrival_time': 0, 'burst_time': 8}, {'name': 'P2', 'arrival_time': 1, 'burst_time': 4}, {'name': 'P3', 'arrival_time': 2, 'burst_time': 9}, ... ] ``` 在这个列表中,每个进程有一个名称、到达时间和执行时间。你可以根据自己的需要修改这些信息,来测试这些进程调度算法的实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Jellyfish Knight

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

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

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

打赏作者

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

抵扣说明:

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

余额充值