操作系统--基于Linux的处理机调度时间片轮转法(超详细/设计/实验/作业/练习)

本文介绍了基于Linux的操作系统课程中的处理机调度实验,重点讲解了时间片轮转法的原理和实现。通过使用进程控制块(PCB),模拟多进程环境下的调度过程,展示了如何在Linux环境下进行进程调度的实践操作。
摘要由CSDN通过智能技术生成

课程名:操作系统原理及Linux应用

内容/作用:设计/实验/作业/练习

学习:基于Linux的处理机调度时间片轮转法

一、前言

  1. 了解Linux下Emacs编辑器的使用方法,掌握各种常用的键盘操作命令;
  2. 理解并掌握处理机调度算法。

二、环境与设备

1.软件:虚拟机VMware
2.环境:Linux系统环境

三、原理

   在采用多道系统的设计程序中,往往有若干进程同时处于就绪状态。当就绪状态进程数大于处理机数时,就必须按照某种策略来决定哪些进程优先占用处理机。本实验模拟在单处理机情况下处理机调度。

1、优先调度算法实现处理机的调度:
设计思路:

   1)每个进程用一个进程控制块PCB来代表,进程控制块包括进程名(进程的标识)、指针(按优先数的大小把进程连成队列,用指针指出下一个进程的进程控制块首地址,最后一个进程中的指针为"0")、要求运行时间、优先数、状态(就绪、结束);
   2)每次运行处理机调度程序前,为每个进程确定它的"优先数"和"要求运行时间";
   3)把给定的进程按优先数的大小连成队列,用一单元指出队首进程;
   4)每模拟执行一次进程,优先数减一,要求运行时间减一;
   5)如果要求运行的时间>=0,再将它加入队列(按优先数的大小插入,重置队首标志);如果要求运行的时间=0,那么把它的状态修改为结束,且退出队列;
   6)若就绪队列不为空,重复上述,直到所有的进程都结束;
   7)程序有显示和打印语句,每次运行后显示变化。

2、按时间片轮转法实现处理机调度:
设计思路:

   1)每个进程用一个进程控制块PCB来代表,进程控制块包括进程名(进程的标识)、指针(把进程连成循环队列,用指针指出下一个进程的进程控制块首地址,最后一个进程中的指针指出第一个进程的进程控制块首地址)、已运行时间、状态(就绪、结束);
   2)每次运行处理机调度程序前,为每个进程确定它的"要求运行时间";
   3)用指针把给定的进程按顺序排成循环队列,用另一标志单元记录轮到的进程;
   4)每模拟运行一次进程,已运行时间加一;
   5)进程运行一次后,把该进程控制块的指针值送到标志单元,以指示下一个轮到的进程。若该进程要求运行时间≠已运行时间,未执行结束,待到下一轮再执行;若要求运行时间=已运行时间,状态改为结束,退出队列;
   6)若就绪队列不为空,重复步骤四和五;
   7)程序有显示和打印语句,每次运行后显示变化。

四、内容

1、时间片轮转法:

#include<stdio.h> 
#include<queue>
#include<math.h>
#include<vector>
#include<iostream>
#include <iomanip>
using namespace std;

/*进程的数据结构*/
struct PCB
{
    int ID;//进程ID
    double in_time;//进程的进入时间
    double res_time;//进程的响应时间
    double l_time;//进程的剩余时间
};

/*进程调度函数                                    */
/*输入:进程队列prs,时间片timeslice                */
/*输出:进程状态表                                */    
void ProcessScheduling(queue<PCB>prs,double timeslice)
{
    cout << left;
    queue<PCB>ex_prs;//就绪队列,该队列中的进程是等待执行的
    ex_prs.push(prs.front());//第一个进程首先进入就绪队列
    prs.pop();//将第一个进程退出进程队列
    double slice_start;//时间片开始时间
    double slice_end = 0;//时间片结束时间
    cout << "----------------------------------进程状态表------------------------------------" << endl;
    cout <<setw(15)<<"进程ID" << "|" << setw(15) << "到达时间" << "|" <<setw(15) << "总响应时间" << "|" << setw(15) << "时间片开始时间"<<"|" << setw(15) <<"时间片结束时间"<<"|"<< endl;
    cout << "--------------------------------------------------------------------------------" << endl;
    while (!prs.empty()||!ex_prs.empty())
    {
        slice_start = slice_end;//更新时间片开始与结束时间
        slice_end += timeslice;//每次增加一个时间片的时间
        while (!prs.empty())
        //每次执行一个进程前,将能在此进程占用cpu期间进入就绪队列的进程加入就绪队列
        {
            if (prs.front().in_time > slice_end)break;
            ex_prs.push(prs.front());
            prs.pop();
            if (ex_prs.size() == 1)
            {
                slice_start = slice_end;
                slice_end += timeslice;
            }
        }
        //如果就绪队列为空则继续while循环
        if (ex_prs.empty())continue;
        //如果剩余时间小于或等于时间片
        if (ex_prs.front().l_time <= timeslice)
        {
            ex_prs.front().l_time = 0;//将进程的剩余时间置为0(可有可无)
            cout << setw(15) << ex_prs.front().ID << "|" << setw(15) << ex_prs.front().in_time << "|" << setw(15) << ex_prs.front().res_time << "|" << setw(15) << slice_start<<"|"<< setw(15) << slice_end<<"|"<< endl;
            ex_prs.pop();
        }
        else
        {
            ex_prs.front().l_time -= timeslice;//将进程的剩余时间减少一个时间片
            cout << setw(15) << ex_prs.front().ID << "|" << setw(15) << ex_prs.front().in_time << "|" << setw(15) << ex_prs.front().res_time << "|" << setw(15) << slice_start << "|" << setw(15) << slice_end <<"|"<< endl;
            //将队首进程置于队尾
            PCB tmp_pr = ex_prs.front();
            ex_prs.pop();
            ex_prs.push(tmp_pr);
        }

    }
    cout << "--------------------------------------------------------------------------------" << endl;
}
int main()
{
    queue<PCB>prs;
    //总响应时间
    double allres_time = 0;
    //时间片
    double timeslice = 0;
    PCB    pr1, pr2, pr3;

    pr1 = { 1,0,10,10 };
    pr2 = { 2,1,5,5 };
    pr3 = { 3,2,5,5 };
    allres_time += pr1.res_time + pr2.res_time + pr3.res_time;
    timeslice = allres_time / 3;
    prs.push(pr1);
    prs.push(pr2);
    prs.push(pr3);
    cout << "时间片为:" << timeslice << endl;
    ProcessScheduling(prs, timeslice);
    cout << "添加进程?(y/n):";
    char i;
    cin >> i;

    while (i-'y'==0)
    {
        PCB pr;
        cout << "请输入进程ID:";
        cin >> pr.ID;
        cout << "请输入进程到达时间:";
        cin >> pr.in_time;
        cout << "请输入进程响应时间:";
        cin >> pr.res_time;
        cout << "请输入进程剩余时间:";
        cin >> pr.l_time;
        prs.push(pr);
        allres_time += pr.res_time;
        timeslice = allres_time / prs.size();
        cout << "时间片为:" << timeslice << endl;
        ProcessScheduling(prs, timeslice);
        cout << "继续添加进程?(y/n):";
        cin >> i;
    }
    return 0;
}


五、总结与分析

   思路:先主函数输入要进行调度的进程数,然后调用函数create(),把进程的信息输入,再调用函数insert(),把输入的函数按照优先数的大小排成链表,然后调用函数prio()实现优先数调度。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序员老茶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值