操作系统调度算法模拟实现(SJF SRTN)

代码实现  
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<map>
#include<string>
#include<cmath>
#include<bitset>
#include<sstream>//切割strtream头文件
#include<climits>//INT_MAX文件
#include <utility>
using i64 = int64_t;
using namespace std;
#define int i64
#define endl '\n'
#define AC return 0;
#define WA cout << "SHU_YUAN" << endl;
const int maxn = 1e6 + 10;
int n, m, k, d, T = 1, A, B;

class PCB {  
private:  
    int id; // 进程id  
    double Arrival_time; // 进程到达就绪队列的时间  
    double Running_time; // 进程预计剩余在CPU运行时间  
    double Turnaround_time; //进程的周转时间
public:  
    PCB(int a, double b, double c, double d = 0) : id(a), Arrival_time(b), Running_time(c), Turnaround_time(d) {  
       // cout << "进程" << id << "创建完成" << endl;  
    }  
    int getId() const { return id; }  
    double getArrivalTime() const { return Arrival_time; }  
    double getRunningTime() const { return Running_time; }  
    double getTurnaround_time() const { return Turnaround_time; }  
    void Set_Turnaround_time(const double x) {Turnaround_time = x;}
};  

// 自定义比较器,用于优先队列  
struct Compare {  
    bool operator()(const PCB& p1, const PCB& p2) {  
        return p1.getRunningTime() > p2.getRunningTime(); // 短任务优先  
    }  
};  

priority_queue<PCB, vector<PCB>, Compare> Q; //模拟就绪队列
vector<PCB>v; //模拟后备队列

void SJF() {  
    // 实现非抢占式短任务优先调度算法的逻辑  
    
    vector<PCB> ans;// 记录完成作业的进程状态 
    double OS_time = 0.0; // 最近一次进行调度和当前进程任务完成时间
    double avge = 0.0;// 计算平均周转时间
    while(!Q.empty() || !v.empty())
    {//当后备队列和就绪队列中存在进程
    	
    	while(!v.empty() && v[0].getArrivalTime() <= OS_time)
    	{  //模拟进程创建态 -> 就绪态
    		cout << "进程" << v[0].getId() << "进入就绪队列" << endl;
    		Q.emplace(v[0]);
    		v.erase(v.begin());
    	}
    	
    	if(Q.empty() && !v.empty())
    	{//如果就绪队列为空, 而后备队列中有未就绪的进程,跳转到就绪时间
    	    cout << "进程" << v[0].getId() << "进入就绪队列" << endl;
    		OS_time = v[0].getArrivalTime();
    		v.erase(v.begin());
    	}
    	
    	while(!Q.empty())
    	{
    		auto x = Q.top();
    		Q.pop();
    		cout << "进程" << x.getId() << "进入运行态" << endl;
    		OS_time += x.getRunningTime();
    		cout << "进程" << x.getId() << "完成" << endl;
    		x.Set_Turnaround_time(OS_time - x.getArrivalTime());
    		ans.emplace_back(x);
    	}
    }
    for(auto& x : ans)	avge += x.getTurnaround_time();//求各进程周转时间之和
    cout << (double)(avge / ans.size()) << endl;
}  

void solve() 
{  
	cin >> n;
    //创建进程
    for (int i = 1; i <= n; i++) 
    {  
        int id;  
        double arrival_time, running_time;  
        cin >> id >> arrival_time >> running_time;  
        v.emplace_back(PCB(id, arrival_time, running_time));   
    } 
    std::sort(v.begin(), v.end(), [&](const auto &x, const auto &y) {  
        return x.getArrivalTime() < y.getArrivalTime();  
    });  //按到达时间初步排序
    
    SJF();
}  


signed main() {
    cin.tie(0) -> sync_with_stdio(false);
    int T = 1;
    //cin >> T;
    while (T--) solve();
    return 0;
}
流程图:

测试样例:

输入:

5

1 0.0 9

2 0.4 4

3 1.0 1

4 5.5 4

5 7 2

输出:

进程1进入就绪队列

进程1进入运行态

进程1完成

进程2进入就绪队列

进程3进入就绪队列

进程4进入就绪队列

进程5进入就绪队列

进程3进入运行态

进程3完成

进程5进入运行态

进程5完成

进程2进入运行态

进程2完成

进程4进入运行态

进程4完成

10.62

 

代码实现 
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<map>
#include<string>
#include<cmath>
#include<bitset>
#include<sstream>//切割strtream头文件
#include<climits>//INT_MAX文件
#include <utility>
using i64 = int64_t;
using namespace std;
#define int i64
#define endl '\n'
#define AC return 0;
#define WA cout << "SHU_YUAN" << endl;
const int maxn = 1e6 + 10;
int n, m, k, d, T = 1, A, B;

class PCB {  
private:  
    int id; // 进程id  
    double Arrival_time; // 进程到达就绪队列的时间  
    double Running_time; // 进程预计剩余在CPU运行时间  
    double Turnaround_time; //进程的周转时间
public:  
    PCB(int a, double b, double c, double d = 0) : id(a), Arrival_time(b), Running_time(c), Turnaround_time(d) {  
        // cout << "进程" << id << "创建完成" << endl;  
    }  
    int getId() const { return id; }  
    double getArrivalTime() const { return Arrival_time; }  
    double getRunningTime() const { return Running_time; }  
    double getTurnaround_time() const { return Turnaround_time; }  
    void Set_Turnaround_time(const double x) {Turnaround_time = x;}
    void Set_Running_time(const double x) {Running_time = x;}
};  

// 自定义比较器,用于优先队列  
struct Compare {  
    bool operator()(const PCB& p1, const PCB& p2) {  
        return p1.getRunningTime() > p2.getRunningTime(); // 短任务优先  
    }  
};  

priority_queue<PCB, vector<PCB>, Compare> Q; //模拟就绪队列
vector<PCB>v; //模拟后备队列

void SRTN() {  
    // 实现抢占式短任务优先调度算法的逻辑  
    
    vector<PCB> ans;//记录完成作业的进程状态 
    double OS_time = 0.0;  double avge = 0.0;//计算平均周转时间
    
    while(!Q.empty() || !v.empty())
    {//当后备队列和就绪队列中存在进程
    	double Next_time = v.at(0).getArrivalTime(); // 新进程进入就绪队列的时间
    	while( !v.empty() && v.at(0).getArrivalTime() == Next_time)
    	{ //批次将后备队列在Next_time时刻的申请完相应运行资源的进程进入就绪队列
    		cout << "进程" << v.at(0).getId() << "进入就绪队列" << endl;
    		Q.emplace(v[0]);
    		v.erase(v.begin());
    	}
    	double Next_time2 = -1;//-1表示无进程在后备队列
    	while(!Q.empty())
    	{
    		if(!v.empty())Next_time2 = v.at(0).getArrivalTime(); // 下一次新进程进入就绪队列的时间
    		else Next_time2 = -1;
    		cout << OS_time << ' ' << Next_time2 << endl;
    		if(-1 != Next_time2)
    		{
    			auto x = Q.top();
    			Q.pop();
    			double T_runtime = 0.0;
    			cout << "进程" << x.getId() << "进入运行态" << endl;
    			if(Next_time2 - OS_time <= x.getRunningTime())
    			{
    				cout << "进程" << x.getId() << "本次运行了" << Next_time2 - OS_time << "ms" << endl;
    				x.Set_Running_time(x.getRunningTime() - (Next_time2 - OS_time)); 
    				cout << "进程" << x.getId() << "转为就绪态" << endl;
    				if(0 == x.getRunningTime())cout << "进程" << x.getId() << "运行完成" << endl;
    				else 
    				{
    					cout << "进程" << x.getId() << "还需运行" << x.getRunningTime() << "s" << endl;
    					Q.emplace(x);
    				}
    			    OS_time = Next_time2;
    				while( !v.empty() && v.at(0).getArrivalTime() == Next_time2)
    				{ 
    					cout << "进程" << v.at(0).getId() << "进入就绪队列" << endl;
    					Q.emplace(v[0]);
    					v.erase(v.begin());
    				}	
    			}
    			else
    			{
    				OS_time += x.getRunningTime();
    				cout << "进程" << x.getId() << "本次运行了" << x.getRunningTime() << "ms,完成作业" << endl;
    				x.Set_Turnaround_time(OS_time - x.getArrivalTime());
    				ans.emplace_back(x);
    			}
    		}
    		else
    		{
    			while(!Q.empty())
    			{
    				auto x = Q.top();
    				Q.pop();
    				cout << "进程" << x.getId() << "进入运行态" << endl;
    				OS_time += x.getRunningTime();
    				cout << "进程" << x.getId() << "本次运行了" << x.getRunningTime() << "ms,完成作业" << endl;
    				x.Set_Turnaround_time(OS_time - x.getArrivalTime());
    				ans.emplace_back(x);
    			}
    		}
    	}
    }
     
    for(auto& x : ans)	avge += x.getTurnaround_time();//求各进程周转时间之和
    cout << (double)(avge / ans.size()) << endl;
}  

void solve() 
{  
	cin >> n;
    //创建进程
    for (int i = 1; i <= n; i++) 
    {  
        int id;  
        double arrival_time, running_time;  
        cin >> id >> arrival_time >> running_time;  
        v.emplace_back(PCB(id, arrival_time, running_time));   
    } 
    std::sort(v.begin(), v.end(), [&](const auto &x, const auto &y) {  
        return x.getArrivalTime() < y.getArrivalTime();  
    });  //按到达时间初步排序
    
    SRTN();
}  


signed main() {
    cin.tie(0) -> sync_with_stdio(false);
    int T = 1;
    //cin >> T;
    while (T--) solve();
    return 0;
}
流程图:

 

测试样例:

输入:

5

3 1.0 1

4 5.5 4

5 7 2

1 0.0 9

2 0.4 4

输出

进程1进入就绪队列

0 0.4

进程1进入运行态

进程1本次运行了0.4ms

进程1转为就绪态

进程1还需运行8.6s

进程2进入就绪队列

0.4 1

进程2进入运行态

进程2本次运行了0.6ms

进程2转为就绪态

进程2还需运行3.4s

进程3进入就绪队列

1 5.5

进程3进入运行态

进程3本次运行了1ms,完成作业

2 5.5

进程2进入运行态

进程2本次运行了3.4ms,完成作业

5.4 5.5

进程1进入运行态

进程1本次运行了0.1ms

进程1转为就绪态

进程1还需运行8.5s

进程4进入就绪队列

5.5 7

进程4进入运行态

进程4本次运行了1.5ms

进程4转为就绪态

进程4还需运行2.5s

进程5进入就绪队列

7 -1

进程5进入运行态

进程5本次运行了2ms,完成作业

进程4进入运行态

进程4本次运行了2.5ms,完成作业

进程1进入运行态

进程1本次运行了8.5ms,完成作业

6.8

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值