操作系统第一次实验——短作业优先调度算法(SJF)

一、实验目的:

目的:了解并掌握作业调度的功能,熟悉并掌握各种作业调度算法。

任务:模拟实现先来先服务或者短作业优先调度算法。

二、实验内容:

1、实验内容

模拟实现SJF调度。

设置作业体:作业名,作业的到达时间,服务时间,作业状态(W——等待,R——运行,F——完成),作业间的链接指针;

作业初始化:由用户输入作业名、服务时间、到达时间进行初始化,同时,初始化作业的状态为W。

显示函数:在作业调度前、调度中和调度后进行显示。

排序函数:对等待状态的作业按照调度算法排序(不同的调度算法排序方式不同),注意考虑到达时间。

调度函数:每次从等待队列队首调度已到达的适合的作业执行,状态变化。当服务结束时,状态变为F。

删除函数:撤销状态为F的作业。

2实验要求

(1)测试数据可以随即输入或从文件中读入;

(2)必须要考虑到作业的到达时间;

(3)最终能够计算每一个作业的周转时间、带权周转时间。

三、实验代码 (C++)

1、首先定义函数体

struct process
{
    string pid;        //作业名(作业号)
    double come_time;  //到达时
    double run_time;   //运行时
    double begin_time; //开始时
    double over_time;  //完成时
    double round_time; //周转时
    double avg_time;   //带权周转时
    double HRR;        //响应比
    char state;		   // 状态 
	double need_time;  // 所剩余需要服务的时间 
} pc[MAXSIZE];         //作业数

2、定义完函数体后,对进程进行排序算法。

bool CmpByComeTime(process p1, process p2) // 按到达时间正序排序
{
    return p1.come_time < p2.come_time;
}
bool CmpByPid(process p1, process p2) // 按id号正序排序
{
    return p1.pid < p2.pid;
}
bool CmpByRunTime(process p1, process p2) // 按运行时长正序排序
{
    return p1.run_time == p2.run_time ? p1.come_time < p2.come_time : p1.run_time < p2.run_time;
}

 3、写完排序函数后,计算进程的开始时间与到达时间

void get_beginAndOver_time() // 计算作业的开始时间与完成时间
{
    for (int i = 0; i < number; i++)
    {
        if (i == 0)
        {
            pc[i].begin_time = pc[i].come_time; // 第一个作业的开始时即为其到达时
        }
        else
        {
            pc[i].begin_time = pc[i - 1].over_time; // 否则后一作业的开始时为前一个作业的完成时
        }
        pc[i].over_time = pc[i].begin_time + pc[i].run_time; // 作业完成时 = 开始时间 + 运行时间
    }
}

4、进行对周转时间,带权周转时间的计算

  1. 完成时间=开始时间+服务时间
  2. 周转时间=完成时间-到达时间
  3. 带权周转时间=周转时间/服务时间
void get_roundAndAvg_time() // 计算作业的周转时间与带权周转时间
{
    for (int i = 0; i < number; ++i)
    {
        pc[i].round_time = pc[i].over_time - pc[i].come_time;     // 周转时 = 完成时间 - 到达时间
        pc[i].avg_time = pc[i].round_time * 1.0 / pc[i].run_time; // 平均周转时 = 周转时间 / 运行时间
    }
}

 5、计算完成后,写SJF的函数体

void SJF() // SJF(short job first):根据作业的运行时间从小到大依次执行
{
    sort(pc, pc + number, CmpByComeTime);    // 先按到达时排序
    sort(pc + 1, pc + number, CmpByRunTime); // 再按运行时排序
    get_beginAndOver_time();
    get_roundAndAvg_time();
}

四、实验结果 

如图

 

五、完整代码

#include <iostream>
#include <algorithm>
using namespace std;
#define MAXSIZE 5 // 作业数
int number; // 用户输入的进程数量
struct process
{
    string pid;        //作业名(作业号)
    double come_time;  //到达时
    double run_time;   //运行时
    double begin_time; //开始时
    double over_time;  //完成时
    double round_time; //周转时
    double avg_time;   //带权周转时
    double HRR;        //响应比
    char state;		   // 状态 
	double need_time;  // 所剩余需要服务的时间 
} pc[MAXSIZE];         //作业数
bool CmpByComeTime(process p1, process p2) // 按到达时间正序排序
{
    return p1.come_time < p2.come_time;
}
bool CmpByPid(process p1, process p2) // 按id号正序排序
{
    return p1.pid < p2.pid;
}
bool CmpByRunTime(process p1, process p2) // 按运行时长正序排序
{
    return p1.run_time == p2.run_time ? p1.come_time < p2.come_time : p1.run_time < p2.run_time;
}

void get_beginAndOver_time() // 计算作业的开始时间与完成时间
{
    for (int i = 0; i < number; i++)
    {
        if (i == 0)
        {
            pc[i].begin_time = pc[i].come_time; // 第一个作业的开始时即为其到达时
        }
        else
        {
            pc[i].begin_time = pc[i - 1].over_time; // 否则后一作业的开始时为前一个作业的完成时
        }
        pc[i].over_time = pc[i].begin_time + pc[i].run_time; // 作业完成时 = 开始时间 + 运行时间
    }
}
void get_roundAndAvg_time() // 计算作业的周转时间与带权周转时间
{
    for (int i = 0; i < number; ++i)
    {
        pc[i].round_time = pc[i].over_time - pc[i].come_time;     // 周转时 = 完成时间 - 到达时间
        pc[i].avg_time = pc[i].round_time * 1.0 / pc[i].run_time; // 平均周转时 = 周转时间 / 运行时间
    }
}

void SJF() // SJF(short job first):根据作业的运行时间从小到大依次执行
{
    sort(pc, pc + number, CmpByComeTime);    // 先按到达时排序
    sort(pc + 1, pc + number, CmpByRunTime); // 再按运行时排序
    get_beginAndOver_time();
    get_roundAndAvg_time();
}

void qianprint()
{
	cout << endl;
    cout << "作业名" << '\t' << "到达时" << '\t' << "运行时" << '\t'
	         << "开始时" << '\t' << "完成时" << '\t' << "状态" << '\t'
	         << endl;
    for (int i = 0; i < number; ++i)
    {
        /* code */
//		sum_round_time = pc[i].over_time;
		pc[i].state='W';
	}
    for (int i = 0; i < number; ++i)
    {

        cout << pc[i].pid << '\t' << pc[i].come_time << '\t'
	             << pc[i].run_time << '\t' << pc[i].begin_time << '\t'
	             << pc[i].over_time << '\t' << pc[i].state<<'\t' << endl;
    }
}
void printProcess() // 打印作业的过程 
{
	double atime=1;
	double sum_round_time = 0.0;
	for (int i = 0; i < number; ++i)
    {
        /* code */
		sum_round_time = pc[i].over_time;
		pc[i].state='W';
	}
//	cout<<sum_round_time<<endl;
	for (atime;atime<=sum_round_time;++atime){
		cout<<'\t'<<endl; 
		cout << "第"<<atime<<"个时间周期" <<'\t'<< endl;
		cout << endl;
	    cout << "作业名" << '\t' << "到达时" << '\t' << "运行时" << '\t'
	         << "开始时" << '\t' << "需要时" << '\t' << "状态" << '\t'
	         << endl;
	    for (int i = 0; i < atime&&i<number; ++i)
    	{
    		for (int j = 0; j < number; ++j)
    		{
    			
		        if (atime==pc[j].come_time&&(pc[j-1].state=='\0'||pc[j-1].state=='F'))
				{
					pc[j].state='R';
				}
				else if(atime>=pc[j].over_time){
					pc[j].state='F';
					pc[j+1].state='R';
				}
			}
		pc[i].need_time=pc[i].over_time-atime;
		if(pc[i].need_time>=0)
		{
			pc[i].need_time=pc[i].need_time;
			
		}
		else
		{
			pc[i].need_time=0;
		}
		if(atime>=pc[i].come_time){
			 cout << pc[i].pid << '\t' << pc[i].come_time << '\t'
	             << pc[i].run_time << '\t' << pc[i].begin_time << '\t'
	             << pc[i].need_time << '\t' << pc[i].state<<'\t' << endl;
		} 
    	}     
    }
        
    
}

void printResult() // 打印输出作业的各个时间值
{
    cout << "执行顺序:"; // << endl
    for (int i = 0; i < number; ++i)
    {
        /* code */
        cout << pc[i].pid<< " ";
        
    }
    cout << endl;
    cout << "作业名" << '\t' << "到达时" << '\t' << "运行时" << '\t'
         << "开始时" << '\t' << "完成时" << '\t' << "周转时" << '\t'
         << "带权周转时" << '\t' << endl;
    sort(pc, pc + number, CmpByPid);
    double sum_round_time = 0.0;
    double avg_sum_round_time = 0.0; // 平均周转时间
    double sum_avg_time = 0.0;
    double avg_sum_avg_time = 0.0; // 平均带权周转时间
    for (int i = 0; i < number; ++i)
    {
        sum_round_time += pc[i].round_time;
        sum_avg_time += pc[i].avg_time;
        cout << pc[i].pid << '\t' << pc[i].come_time << '\t'
             << pc[i].run_time << '\t' << pc[i].begin_time << '\t'
             << pc[i].over_time << '\t' << pc[i].round_time << '\t'
             << pc[i].avg_time << endl;
    }
    avg_sum_round_time = sum_round_time * 1.0 / number;
    avg_sum_avg_time = sum_avg_time * 1.0 / number;
    cout << "平均周转时间: " << avg_sum_round_time << endl
         << "平均带权周转时间: " << avg_sum_avg_time << endl;
}
int main() // 入口函数
{
	int atime=1;
    cout << "请输入进程个数:";
    cin >> number;
    cout << endl;
    cout << "请分别输入进程的名称、到达时间、服务时间:" << endl;
    for (int i = 0; i < number; i++)
    {
        cin >> pc[i].pid >> pc[i].come_time >> pc[i].run_time;
    }
    cout << endl;
    SJF();
    cout << "运行前的任务:" <<'\t'<< endl;
    qianprint();
    cout << "运行中的任务调度过程:" <<'\t'<< endl;
    printProcess();
    cout << "the results of SJF are:" << endl;
	printResult();
    
    system("pause");
    return 0;
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

梁弋生

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

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

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

打赏作者

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

抵扣说明:

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

余额充值