操作系统实验实验一进程调度

实验内容

设 计 程 序 模 拟 进 程 的 轮 转 法 调 度 过 程 。 假 设 初 始 状 态 为 : 有 n 个 进 程 处 于 就 绪 状 态 , 有 m 个 进程 处 于 阻 塞 状 态 。 采 用 轮 转 法 进 程 调 度 算 法 进 行 调 度 。 调 度 过 程 中 , 假 设 处 于 执 行 状 态 的 进 程 不 会 阻塞 , 且 每 过 t 个 时 间 片 系 统 释 放 资 源 , 唤 醒 处 于 阻 塞 队 列 队 首 的 进 程 。

程 序 要 求 如 下 :
1 ) 输 出 系 统 中 进 程 的 调 度 次 序 ;
2 ) 计 算 CPU 利 用 率 。

说明

请注意,这段程序只实现了RR算法的最简单的一种情形,但刚好满足实验一的最低要求🤣

注意:如果遇到在visual stdio编译报错,报错内容是std::至少需要c++17。请查询如何修改编译器C++编译版本

实现步骤

设置一个符合实验要求的,可以标识进程的PCB控制块

struct PCB_Type {
    char name;      // 进程名
    int state;      // 进程状态 0--阻塞 1--就绪 2--执行
    int cpu_time;   // 运行需要的CPU时间(需要的服务时间)

    PCB_Type() : name('\0'), state(-1), cpu_time(0) {}
};

using PCB = PCB_Type;

实现一个RR类,包含必要的两个类成员

private:
//包含#include <queue>头文件
    queue<PCB *> Ready_Que;         // 就绪队列
    queue<PCB *> Blocked_Que;       // 阻塞队列

实现类成员函数,初始队列

// 初始化两个队列
inline void init_que() {
	int n, m;    //n--处于就绪的进程个数 m--处于阻塞的进程个数
	cout << "请输入就绪进程的个数和阻塞进程的个数:";
	cin >> n >> m;
	for (int i = 1; i <= n; ++i) {
		PCB *process = new PCB();
		printf("输入就绪进程%d的进程名和要求服务时间:", i);
		cin >> process->name >> process->cpu_time;
		// 初始化到就绪队列
		process->state = 1;
		Ready_Que.push(process);
	}

   for (int i = 1; i <= m; ++i) {
         PCB *process = new PCB();
         printf("输入阻塞进程%d的进程名和要求服务时间:", i);
         cin >> process->name >> process->cpu_time;
         // 初始化到阻塞队列
         process->state = 0;
         Blocked_Que.push(process);
     }
 }

实现类成员函数,模拟调度

// 模拟调度
inline void dispatch() {
    cout << "输入t:";
    int t;      //每过t个时间片 从阻塞队列中唤醒队首进程
    cin >> t;

    cout << "开始调度\n";
    int time = 1;
    while (!Ready_Que.empty() || !Blocked_Que.empty()) {
        printf("时间片%d:", time);
        if (Ready_Que.empty()) {
            cout << "空闲一个时间片\n";
            if (time % t == 0 && !Blocked_Que.empty()) {     
                FBTR();		// 将处于阻塞队列首进程放入就绪队列
            }
        } else if (!Ready_Que.empty()) {
            if (time % t == 0 && !Blocked_Que.empty()) {     
                FBTR();		// 将处于阻塞队列首进程放入就绪队列
            }
            PCB *process = Ready_Que.front();
            printf("进程%c调度\n", process->name);
            Ready_Que.pop();
            --process->cpu_time;
            if (process->cpu_time == 0) {
                printf("进程%c完成\n", process->name);
            } else {
                Ready_Que.push(process);
            }
        }
        ++time;
    }
}

独立了一份把处于阻塞队列的首进程放入就绪队列的模块
把它设置为protected属性,只用于类内部调用

protected:
// 这个点被老师问到了,其实是from block to ready😊
inline void FBTR() {   //将阻塞队列队首进程放入就绪队列
    PCB *process = Blocked_Que.front();
    process->state = 1;
    Ready_Que.push(process);
    Blocked_Que.pop();
}

计算CPU利用率见完整代码

完整代码

#include <iostream>
#include <queue>
#include <iomanip>

using namespace std;

void display() {
    printf("******************************\n");
    printf("**\t这是一个模拟RR调度算法的程序\t**\n");
    printf("**\t1.初始就绪队列和阻塞队列\t**\n");
    printf("**\t2.查看初始的队列情况    \t**\n");
    printf("**\t3.开始模拟调度         \t**\n");
    printf("**\t4.计算CPU利用率         \t**\n");
    printf("******************************\n");
}

struct PCB_Type {
    char name;      // 进程名
    int state;      // 进程状态 0--阻塞 1--就绪 2--执行
    int cpu_time;   // 运行需要的CPU时间(需要的服务时间)

    PCB_Type() : name('\0'), state(-1), cpu_time(0) {}
};
using PCB = PCB_Type;

// 基于时间片轮转调度算法(RR)
class RR {
public:
    RR() = default;     // 构造
    ~RR() = default;    // 析构

    // 初始化两个队列
    inline void init_que() {
        int n, m;    //n--处于就绪的进程个数 m--处于阻塞的进程个数
        cout << "请输入就绪进程的个数和阻塞进程的个数:";
        cin >> n >> m;
        for (int i = 1; i <= n; ++i) {
            PCB *process = new PCB();
            printf("输入就绪进程%d的进程名和要求服务时间:", i);
            cin >> process->name >> process->cpu_time;
            // 初始化到就绪队列
            process->state = 1;
            Ready_Que.push(process);
        }
        for (int i = 1; i <= m; ++i) {
            PCB *process = new PCB();
            printf("输入阻塞进程%d的进程名和要求服务时间:", i);
            cin >> process->name >> process->cpu_time;
            // 初始化到阻塞队列
            process->state = 0;
            Blocked_Que.push(process);
        }
    }

    // 模拟调度
    inline void dispatch() {
        cout << "输入t:";
        int t;      //每过t个时间片 从阻塞队列中唤醒队首进程
        cin >> t;
        int _idle_num = 0.0;    // 记录下来调度算法执行中CPU空转情况

        // RR
        cout << "开始调度\n";
        int time = 1;
        while (!Ready_Que.empty() || !Blocked_Que.empty()) {
            printf("时间片%d:", time);
            if (Ready_Que.empty()) {
                ++_idle_num;
                cout << "空闲一个时间片\n";
                if (time % t == 0 && !Blocked_Que.empty()) {     // 将处于阻塞队列首进程放入就绪队列
                    FBTR();
                }
            } else if (!Ready_Que.empty()) {
                if (time % t == 0 && !Blocked_Que.empty()) {     // 将处于阻塞队列首进程放入就绪队列
                    FBTR();
                }
                PCB *process = Ready_Que.front();
                printf("进程%c调度\n", process->name);
                Ready_Que.pop();
                --process->cpu_time;
                if (process->cpu_time == 0) {
                    printf("进程%c完成\n", process->name);
                } else {
                    Ready_Que.push(process);
                }
            }
            ++time;
        }
        this->l = _idle_num, this->All = time - 1;
    }

    // 查看初始的队列信息
    inline void queInfo() const {
        cout << "处于就绪队列的进程有:\n";
        cout << "name state cpu_time\n";
        queue<PCB *> R_cur = Ready_Que;
        while (!R_cur.empty()) {
            PCB *tmp = R_cur.front();
            R_cur.pop();
            cout << setw(4) << tmp->name << setw(4) << tmp->state << setw(4)
                 << tmp->cpu_time << endl;
        }

        cout << "处于阻塞队列的进程有:\n";
        cout << "name state cpu_time\n";
        queue<PCB *> B_cur = Blocked_Que;
        while (!B_cur.empty()) {
            PCB *tmp = B_cur.front();
            B_cur.pop();
            cout << setw(4) << tmp->name << setw(4) << tmp->state << setw(4)
                 << tmp->cpu_time << endl;
        }
    }

    // 计算CPU利用率
    inline void calculate() const {
        auto res = (float) (All - l) / (float) All;
        printf("CPU利用率%.2f%%\n", res * 100.0);
    }

protected:
    inline void FBTR() {   //将阻塞队列队首进程放入就绪队列
        PCB *process = Blocked_Que.front();
        process->state = 1;
        Ready_Que.push(process);
        Blocked_Que.pop();
    }

private:
    queue<PCB *> Ready_Que;         // 就绪队列
    queue<PCB *> Blocked_Que;       // 阻塞队列

    int l = 0, All = 0;		// 用于计算利用率
};

int main() {
    RR J;
    display();
    int step;
    cout << "输入操作指令:";
    cin >> step;
    while (step != 0) {
        switch (step) {
            case 1:
                J.init_que();
                cout << "初始完成!\n";
                break;
            case 2:
                J.queInfo();
                break;
            case 3:
                J.dispatch();
                break;
            case 4:
                J.calculate();
                break;
            default:
                break;
        }
        cout << "输入操作指令:";
        cin >> step;
    }
    return 0;
}

至此,实验一已经完成。

由于本人技术有限,代码中不免存在纰漏,还望见谅。💕💕💕

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

打代码要笑着打

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

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

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

打赏作者

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

抵扣说明:

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

余额充值