专题二+进程调度算法 RR q=1(含做题代码)
总结:到达时间一到对应进程进入,执行队首进程一次,对应的服务时间划一记号(推荐用正字),队首进程未执行到完成的话重新进入队尾,队首进程执行到完成的话出队,下一秒继续执行队首进程,当5个进程全部入队之后只要执行后两步操作。
基本分为3步操作:执行队首进程pi,加标记。进程pj到达进入就绪队列。pi未执行完重新进入就绪队列。
以下题为例
Process: p1 p2 p3 p4 p5
Arrival Time: 0 1 2 3 6
Service TIme: 3 5 5 2 3
p1 p2 p1 p3 p2 p4 p1 p3 p2 p5 p4 p3 p2 p5 p3
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
p2 p5 p3 p3
15 16 17 18 19
就绪队列
0秒时 p1进入就绪队列:p1,p1处于队首运行 p1.servicetime=1,完成操作后到达1秒。
1秒时 p2进入就绪队列:p1p2,此时p1未完成服务时间重新入队,就绪队列为p2p1。
1秒时 p2处于队首运行 p2.servicetime=1,完成操作后到达2秒。
2秒时 p3进入就绪队列:p2p1p3,此时p2未完成重新入队,就绪队列为p1p3p2。
2秒时 p1处于队首运行 p1.servicetime=2,完成操作后到达3秒。
3秒时 p4进入就绪队列:p1p3p2p4,此时p1未完成重新入队,就绪队列:p3p2p4p1。
3秒时 p3处于队首运行 p3.servicetime=1完成操作后到达4秒。
4秒时 p3未完成重新入队:p2p4p1p3。
4秒时 p2处于队首运行 p2.servicetime=2 完成操作后到达5秒。
5秒时 p2未完成重新入队,此时队列:p4p1p3p2。
此时p4队首运行 p4.servicetime=1 完成操作后到达6秒
6秒时 p5入队,为:p4p1p3p2p5。p4未完成重新入队:p1p3p2p5p4。
p1队首运行,p1.servicetime=3 p1完成出队:p3p2p5p4到达7秒
7秒时 p3队首运行,p3.servicetime=2 p3未完成入队:p2p5p4p3到达8秒
8秒时 p2队首运行 p2.servicetime=3 p2未完成入队:p5p4p3p2到达9秒
9秒时 p5队首运行 p5.servicetime=1 p5未完成入队:p4p3p2p5到达10秒
10秒时 p4队首运行 p4.servicetime=2 p4完成出队:p3p2p5到达11秒
11秒时 p3队首运行 p3.servicetime=3 p3未完成入队:p2p5p3到达12秒
12秒时 p2队首运行 p2.servicetime=4 p2未完成入队:p5p3p2到达13秒
13秒时 p5队首运行 p5.servicetime=2 p5未完成入队:p3p2p5到达14秒
14秒时 p3队首运行 p3.servicetime=4 p3未完成入队:p2p5p3到达15秒
15秒时 p2队首运行 p2.servicetime=5 p2完成出队:p5p3到达16秒
16秒时 p5队首运行 p5.servicetime=3 p5完成出队:p3到达17秒
17秒时 p3队首运行 p3.servicetime=5 p3完成入队:p3到达18秒
Process从后往前找最后结束的到最早结束的对应完成时间 Turnaround Time=Finish Time-Arrival Time
Wr=Tr/Ts保留三位小数 T=sum(Tr)/5 W=sum( Wr )/5 (保留两位小数)
算法实现结果图
RR算法代码实现(C++)
/** 来源:网络 **/
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define pii pair<int, int>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
vector<int> ans;
vector<int> G[200];
queue<pii> q;
int at[200],st[200],finit[200],tt[200],rr,n;
double wr[200];
int cmp(int a, int b) { return finit[a] < finit[b]; }
int main()
{
cout << "RR算法代码实现" << endl;
cout << "请输入进程个数:";
cin >> n;
cout << "请输入时间片q:";
cin >> rr;
rep(i, 1, n)
{
cout << "请输入进程 " << i << " 到达时间、服务时间(空格隔开):";
cin >> at[i] >> st[i];
G[at[i]].pb(i);
}
for (auto &i : G[0])
q.push(mp(i, 0));
int ti = 0;
while (!q.empty())
{
pii t = q.front();
q.pop();
rep(i, 1, rr)
{
ans.pb(t.fi);
ti++;
for (auto &i : G[ti])
q.push(mp(i, 0));
t.se++;
if (t.se == st[t.fi])
{
finit[t.fi] = ti;
break;
}
}
if (t.se != st[t.fi])
q.push(t);
}
cout << "Total time: " << ti << endl;
cout << "Gantt chart如下:" << endl;
ti = 0;
for (int i = 0; i < ans.size(); i++)
{
int p = i;
while (p + 1 < ans.size() && ans[p] == ans[p + 1] && (p - i + 1) < rr)
p++, ti++;
ti++;
cout << " " << "P" << ans[i];
i = p;
}
cout << endl;
cout << 0 << " ";
ti=0;
for (int i = 0; i < ans.size(); i++)
{
int p = i;
while (p + 1 < ans.size() && ans[p] == ans[p + 1] && (p - i + 1) < rr)
p++, ti++;
ti++;
cout << ti << " ";
i = p;
}
cout << endl;
string s[200];
s[1] = "Process";
s[2] = "Finish Time";
s[3] = "Arrival Time";
s[4] = "Turnaround Time";
s[5] = "Service Time";
s[6] = "Wr";
rep(i, 1, 6) { cout << s[i] << "\t "; }
cout << endl;
double avtt = 0,avwr = 0;
rep(i, 1, n)
{
tt[i] = finit[i] - at[i];
wr[i] = tt[i] * 1.0 / st[i];
avtt += 1.0 * tt[i] / n;
avwr += 1.0 * wr[i] / n;
}
int tmp[200];
rep(i, 1, n) tmp[i] = i;
sort(tmp + 1, tmp + 1 + n, cmp);
rep(j, 1, n)
{
int i = tmp[j];
cout << "P" << i << "\t\t" << finit[i] << "\t " << at[i]
<< "\t " << tt[i] << "\t " << st[i]
<< "\t ";
printf("%.3f\n", wr[i]);
}
printf("T=%.02f\nW=%.02f\n", avtt, avwr);
return 0;
}
CATS专题四+页面置换算法.Clock算法(含做题代码)
(选择专题四勾选两个核心算法)
PR页面置换
RS访问串 直接抄写,检查长度
RS:6 0 5 0 4 1 6 4 2 7 5 2 0 2 5 7 4 5 1 7 3 6 3 0 1
RAM内存
RAM(主存)共分配物理块 (以5个为例)上面是低地址,下面是高地址。
访问位用*标注(1,1,1,0)、
替换指针NF开始指向最高地址的物理块
1* |
0* |
2* |
5 |
NF |
NF
依次访问已知访问串(RS)页面,若发生缺页中断给出内存中的图表列,否则为空列。
(内存中的图表列个数即是缺页中断的次数)
步骤:
访问6不在,发生缺页中断,NF指空,6直接装入且访问位A=1,替换指针NF下移。RAM填空。
1*(NF) |
0* |
2* |
5 |
6* |
访问0在,RAM空。
1*(NF) |
0* |
2* |
5 |
6* |
访问5在,A=1,注意NF不移动,RAM空。
1*(NF) |
0* |
2* |
5* |
6* |
访问0在,RAM空
1*(NF) |
0* |
2* |
5* |
6* |
访问4不在,缺页中断,由于NF位置指向1 的A=1,则A=0,NF指向0的A=1,则A=0,NF下移,同理,循环一周后内存中所有页面访问位A=0,NF指向1,此时1的A=0被4号页面置换,4号页的A=1,NF指针下移。RAM填空、PR填置换出去的1。
PR
1 |
4* |
0(NF) |
2 |
5 |
6 |
访问1不在,缺页中断,由于NF指向的0的A=0替换,1的A=1,NF指针下移,RAM填空,PR填被置换出去的0。
PR
0 |
4* |
1* |
2(NF) |
5 |
6 |
访问6存在,6号页的A=1。PAM空。
4* |
1* |
2(NF) |
5 |
6* |
访问4存在,A=1.PAM空
4* |
1* |
2(NF) |
5 |
6* |
访问2存在,A=1,PAM空
4* |
1* |
2*(NF) |
5 |
6* |
访问7不存在,缺页中断,NF指向2的A=0,NF下移,5的A=0置换为7,A=1,NF下移。RAM填空,PR填置换的5。
PR
5 |
4* |
1* |
2 |
7* |
6*(NF) |
往后操作相同
最后 Page-Faults PF= 12(RAM不为空的列数)
Page-Roplacements PR=11 (PR不为空的列数)
依次被置换的页面:PR依次填用“,”隔开。
Pages to be replaced list: 1,0,5,2,6,4,1,5,2,0,4
List separator is comma(,)(逗号用英文半角)
页面置换算法——Clock算法代码实现(C++)
/**
来源:网络
**/
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#define N 200
#define rep(i, a, b) for (int i = a; i <= b; i++)
using namespace std;
struct node {
int index;
int page;
int status;
};
int PR[N];
int RS[N];
node ram[10];
node _ram[10][N];
node *p = NULL;
int frame; // 物理块个数
int _page; // 已装入内存的页面个数
int rs_num; // 页面序列个数
int PF_NUM, PR_NUM;
void clock() {
rep(i, 0, rs_num - 1) {
int flag = 0;
rep(j, 1, frame) {
if (ram[j].page == RS[i]) {
ram[j].status = 1;
flag = 1;
break;
}
}
if (flag == 1) continue;
int k = p->index;
while (1) {
if (ram[k].status == -1) {
ram[k].page = RS[i];
ram[k].status = 1;
flag = 1;
PF_NUM++; // 页面中断次数++
} else {
if (ram[k].status == 1) {
ram[k].status = 0;
} else if (ram[k].status == 0) {
PR[i] = ram[k].page;
ram[k].page = RS[i];
// cout << RS[i] << "***" << PR[i] << endl;
ram[k].status = 1;
flag = 1;
PF_NUM++; // 页面中断次数++
PR_NUM++; // 页面置换次数++
}
}
if (k == frame) {
p = &ram[1];
} else {
p = &ram[k + 1];
}
k = p->index;
// cout << "p " << p->index << endl;
if (flag == 1) break;
}
rep(j, 1, frame) {
if (ram[j].page == -1) {
// cout << ram[j].index << " "
// << " "
// << "-"
// << " " << endl;
} else {
_ram[j][i].page = ram[j].page;
_ram[j][i].status = ram[j].status;
_ram[j][i].index = ram[j].index;
// cout << ram[j].index << " " << ram[j].page << "-"
// << ram[j].status << endl;
}
}
}
}
void init_data() {
PR_NUM = PF_NUM = 0;
// cout << "test" << PF_NUM << PR_NUM << endl;
rep(i, 0, N - 1) {
PR[i] = -1;
RS[i] = -1;
}
rep(i, 1, 9) {
ram[i].index = i;
ram[i].page = ram[i].status = -1;
rep(j, 0, N - 1) {
_ram[i][j].page = _ram[i][j].status = _ram[i][j].index = -1;
}
}
}
void init() {
cout << "Clock 页面置换算法实现" << endl;
init_data();
cout << "请输入进程物理块个数:";
cin >> frame;
cout << "请输入已装入内存的界面个数:";
cin >> _page;
rep(i, 1, _page) {
cout << "请输入已装入内存的界面 P A状态(空格隔开):";
cin >> ram[i].page >> ram[i].status;
}
int pp;
cout << "指向最高地址 (输入1) 指向最低地址 (输入0):";
cin >> pp;
p = (pp == 1) ? &ram[frame] : &ram[1];
cout << "请输入RS序列 -1结束:";
int temp;
rs_num = 0;
while (cin >> temp && temp != -1) {
RS[rs_num++] = temp;
}
}
void show() {
cout << "################### chart show #################" << endl;
rep(i, 0, rs_num - 1) {
if (PR[i] != -1) {
cout << PR[i] << " ";
} else
cout << " ";
}
cout << endl;
rep(i, 0, rs_num - 1) { cout << RS[i] << " "; }
cout << endl;
rep(j, 1, frame) {
rep(i, 0, rs_num - 1) {
if (_ram[j][i].index == -1) {
cout << " ";
} else {
cout << _ram[j][i].page << " ";
}
}
cout << endl;
}
cout << "################################################" << endl;
cout << "PF: " << PF_NUM << endl;
cout << "PR: " << PR_NUM << endl;
rep(j, 1, frame) { cout << ram[j].page << "-" << ram[j].status << ","; }
cout << endl;
}
int main() {
init();
clock();
show();
return 0;
}