操作系统实验
GitHubID:ITApeDeHao
目录
操作系统实验
(1)处理器调度
(2)同步机构
(3)虚拟存储器
(4)驱动调度
(5)源码
1 .处理器调度
2.同步机构
3.虚拟存储器
4.驱动调度
GitHub查看
(1)处理器调度
设计一个按优先数调度算法实现处理器调度的进程。
(2)同步机构
模拟 PV 操作同步机构,且用 PV 操作解决生产者——消费者问题
(3)虚拟存储器
1.模拟分页式存储管理中硬件的地址转换和产生缺页中断。
2.用先进先出(FIFO)页面调度算法处理缺页中断。
(4)驱动调度
模拟电梯调度算法,对磁盘进行移臂和旋转调度。
(5)源码
1 .处理器调度
Operating_System.h
//
// Created by 86176 on 2022/4/14 0014.
//
#ifndef PROJECT_OPERATING_SYSTEM_H
#define PROJECT_OPERATING_SYSTEM_H
#include<string>
using namespace std;
class Operating_System {
private:
// 创建进程模块
typedef struct Process{
string Process_name;
int Operation_hours=0;
int Required_runtime;
int Priority_number;
char Status='R';
struct Process *next;
}Process;
Process *process;
double time=0;
bool Set_hours(); // 为每个进程计算设置等待时间
void Print(); // 打印所有进程
bool Delete_Process();// 要求运行时间为0 状态位标为“结束”,并且从表中删除该进程。
public:
Operating_System(); // 构造函数
~Operating_System(){} // 析构函数
bool Add_Process(); // 创建新进程将其加入到操作系统中
bool Running(); // 运行当前优先数最大的的一个进程,即第一个进程
};
#endif //PROJECT_OPERATING_SYSTEM_H
Operating_System.cpp
//
// Created by 86176 on 2022/4/14 0014.
//
#include "Operating_System.h"
#include <iostream>
#include <climits>
#include <string>
using namespace std;
Operating_System::Operating_System() {
// 初始默认构造函数
process = new Process; // 为头结点分配空间
process->next = nullptr; // 将后继节点指向空指针
}
bool Operating_System::Add_Process() {
// 创建一个新进程 并将其加入到系统内部
Process *s = process;
auto *p = new Process;
string name;
int times;
int number;
cout << "Please input Process_name" << endl;
cin >> name;
cout << "Please input Required_times" << endl;
cin >> times;
cout << "Please input Priority_number" << endl;
cin >> number;
p->Process_name = name;
p->Required_runtime = times;
p->Priority_number = number;
p->next = s->next;
s->next = p;
cout << "OK" << endl;
return true;
}
// 每次运行设置每个进程的等待时间
bool Operating_System::Set_hours() {
// 计算每次等待时间
auto p = process->next; // 游标指针 设置此指针指向的进程的等待时间
while (p != nullptr){
auto s = process->next; // 与游标指针比较的其他进程的指针
int hours = 0; // 初始等待时间为0
while (s != nullptr){
if (s == p){
s = s->next;
continue;
}
// 循环遍历进程链表,求出 p指针所需的等待时间
if (s->Priority_number >= p->Priority_number && s->Status == 'R') {
for (int i = 0; i <= s->Priority_number - p->Priority_number; i++) {
hours += s->Required_runtime - i;
}
}
s = s->next;
}
p->Operation_hours = hours;
if (p->Status == 'E'){
p->Operation_hours = 0;
}
p = p->next;
}
return true;
}
// 将进程从队列中”删除“
bool Operating_System::Delete_Process() {
if(process->next == nullptr) return false;
auto pre = process;
auto cur = process->next;
while(cur != nullptr) {
if (cur->Required_runtime == 0) {
// 将所需时间为0 的进程的状态设置为 E 。
cur->Status = 'E';
}
cur = cur->next;
pre = pre->next;
}
return true;
}
// 运行进程
bool Operating_System::Running() {
Set_hours(); // 遍历设置队列等待时间
auto p= process->next;
auto s = new Process;
s->Priority_number = INT_MIN;
// 寻找本次所需执行的最高优先数的指针
while (p != nullptr){
if(p->Status == 'E'){
p = p->next;
continue;
}
if(p->Priority_number >= s->Priority_number){
s = p;
}
p = p->next;
}
// 所有的进程都执行完毕后 结束递归调用
if (s->Required_runtime == 0) {
cout << "The current processor is idle ! " << endl;
Print();
return false;
}
// 每次执行进程 将其时间和优先数各减一
s->Priority_number--;
s->Required_runtime--;
cout << "The currently running process is named :" << s->Process_name << endl;
cout << " The running time of the currently running process is :" << s->Required_runtime << endl;
cout << " The priority number of the currently running process is :" << s->Priority_number << endl;
// 输出所有进程的状态信息
Print();
// 检查并结束 不在需要执行的进程
Delete_Process();
// 调用自身 继续执行
Running();
return true;
}
// 输出所有进程状态
void Operating_System::Print() {
auto p = process;
while (p->next){
cout << "Process name : " << p->next->Process_name << " Waiting time :" << p->next->Operation_hours << endl;
cout << "Process Status : " << p->next->Status << endl;
p = p->next;
}
}
调用实现代码:
//
// Created by 86176 on 2022/4/14 0014.
//
#include <iostream>
#include "Operating_System.cpp"
using namespace std;
int main(){
Operating_System process;
for (int i = 0; i < 5;i++) {
process.Add_Process();
}
process.Running();
return 0;
}
2.同步机构
PV.h
//
// Created by 86176 on 2022/4/21 0021.
//
#include <string>
#ifndef PROJECT_PV_H
#define PROJECT_PV_H
using namespace std;
int P(int s); // P原语
int V(int s); // V原语
void Put(char c); // 生产者生产的产品放入商店
char Get(); // 消费者从商店获取产品
char produce(); // 生产者生产产品
void consume(char c);// 消费者消费产品
void GOTO(int L); // 执行PC寄存器的指令
void NOP(); // 空指令
void init(); // 初始化程序
void schedule(); // 处理器调度程序
void pcDoing(); // 处理器指令调度程序
void showPCB(int i); // 输出PCB
#endif //PROJECT_PV_H
PV.cpp
//
// Created by 86176 on 2022/4/21 0021.
//
#include "PV.h"
#include <iostream>
#include<stdio.h>
#include<stdlib.h>
#include <string>
#include <windows.h>
using namespace std;
#define random() (rand()%2)
enum State
{
running,
ready,
waiting,
done
};
struct PCB
{
string pName;
State pState;
int pWaitFor;
int PC;
};
PCB p1, p2;
PCB * pro, *proc;
static char BufferPool[10];
int s1;
int s2;
int in = 0;
int out = 0;
int PC;
int PA[5];
int SA[5];
char c1,c2;
int P(int s){
s--;
if (s < 0){
pro->pState = waiting;
pro->pWaitFor = s;
}
else
pro->pState = ready;
return s;
}
int V(int s){
s++;
if (s <= 0){
proc->pState = ready;
proc->pWaitFor = s;
}
pro->pState = ready;
return s;
}
void Put(char c){
BufferPool[in] = c;
in = (in + 1) % 10;
}
char Get() {
char c = BufferPool[out];
out = (out + 1) % 10;
return c;
}
char produce(){
char s;
cout << " :" << endl;
cin >> s;
return s;
}
void consume(char c){
cout << " :"<<c << endl;
}
void GOTO(int L){
pro->PC = L;
}
void NOP(){
}
void init(){
s1 = 10;
s2 = 0;
p1 = {"Product",ready,s1,0};
p2 = {"Consumer",ready,s2,0};
p1.pState = running;
pro = &p1;
proc = &p2;
for (int i = 0; i < 5; i++){
PA[i] = i;
}
for (int i = 0; i < 5; i++){
SA[i] = i;
}
schedule();
}
void schedule(){
if (pro->pState == running){
pro->pState = ready;
}
if (p1.pState == ready || p2.pState == ready){
if (random() == 0)
{
pro = &p1;
proc = &p2;
}
else
{
pro = &p2;
proc = &p1;
}
if (pro->pState == ready)
{
PC = pro->PC;
pro->pState = running;
pcDoing();
}
}
}
void pcDoing(){
int i = pro->PC;
showPCB(i);
if (p1.pState == running){
int j = PA[i];
switch (j)
{
case 0:c1 = produce(); pro->PC++; break;
case 1:s1 = P(s1); pro->PC++; break;
case 2:Put(c1); pro->PC++; break;
case 3:s2 = V(s2); pro->PC++; break;
case 4:GOTO(0); break;
default:
break;
}
}
if (p2.pState == running){
int j = SA[i];
switch (j)
{
case 0:s2 = P(s2); pro->PC++; break;
case 1:c2 = Get(); pro->PC++; break;
case 2:s1 = V(s1); pro->PC++; break;
case 3:consume(c2); pro->PC++; break;
case 4:GOTO(0); break;
default:
break;
}
}
}
void showPCB(int i){
cout << "--- " << pro->pName << " " << i+1 << " " << "---------" << endl;
Sleep(1000);
}
int main(){
init();
while (true)
schedule();
return 0;
}
3.虚拟存储器
virtual_memory.h
//
// Created by 86176 on 2022/5/11 0011.
//
#ifndef PV_CPP_VIRTUAL_MEMORY_H
#define PV_CPP_VIRTUAL_MEMORY_H
#include <iostream>
#include <iomanip>
using namespace std;
typedef struct Virtual{ // 页表结构
int pagenum; // 页号
int sign; // 标志位,表示是否存入主存中
int main_memory; // 在主存的位置
int where_in_disk; // 在磁盘中的位置
int modify_bit; // 修改位默认为0 如果发生存操作则变为1
}Virtual;
typedef struct Operation{ // 指令
string operate; // 指令操作
int pagenumber; // 操作页号
int unit_number; // 操作字块号
}Operation;
const int MAXSIZE = 7; // 页表长度为 7
const int MAXSIEZ_MAIN = 4;
class virtual_memory { // 分页式虚拟存储系统
private:
Virtual s[MAXSIZE]; // 分页式虚拟存储系统页表
int P[MAXSIEZ_MAIN];
int k;
public:
virtual_memory(); // 初始化页表操作
int Find_absolute_address(Operation operators); // 地址转换
int show(); // 展示页表
int FIFO(int pagenum); // FIFO调度算法解决缺页中断
};
#endif //PV_CPP_VIRTUAL_MEMORY_H
virtual_memory.cpp
//
// Created by 86176 on 2022/5/11 0011.
//
#include "virtual_memory.h"
// 初始化页表操作
virtual_memory::virtual_memory() {
int i = 0;
k = 0;
for(;i<MAXSIZE;i++) {
int status, main_memory, where_in_disk,pagenum;
cout << "请输入页号:" << endl;
cin >> s[i].pagenum;
cout << "请输入标志位:" << endl;
cin >> s[i].sign;
if (s[i].sign == 1) {
cout << "请输入页框号:" << endl;
cin >> s[i].main_memory;
P[k] = s[i].pagenum;
k = (k + 1) % MAXSIEZ_MAIN;
} else {
s[i].main_memory = 0;
}
cout << "请输入在磁盘上的位置:" << endl;
cin >> s[i].where_in_disk;
s[i].modify_bit = 0;
}
}
// 地址转换
int virtual_memory::Find_absolute_address(Operation operators) {
int i, absolute_address;
if(operators.pagenumber >= MAXSIZE || operators.unit_number > 128){
cout << "页号或页框号输入错误,请重新输入" << endl;
return -1;
}
for (i = 0; i < MAXSIZE; ++i) {
if (s[i].pagenum == operators.pagenumber) break;
}
if("存" == operators.operate){
s[i].modify_bit = 1;
}
absolute_address = s[i].main_memory * 128 + operators.unit_number;
if (s[i].sign == 1) {
cout << "绝对地址为: " << s[i].main_memory << " * 128 + "<< operators.unit_number << " = ";
cout << absolute_address << endl;
} else {
FIFO(s[i].pagenum);
cout << "* " << operators.pagenumber << endl;
}
return absolute_address;
}
// 展示页表
int virtual_memory::show() {
cout << "页号\t" << "标志位\t" << "页框号\t" << "在磁盘上的位置\t" << "修改位\t" << endl;
for (int i = 0; i < MAXSIZE; ++i) {
cout << setiosflags(ios::left) << setw(8) << s[i].pagenum << setw(9) << s[i].sign << setw(8) << s[i].main_memory << setw(15) << s[i].where_in_disk << setw(8) << s[i].modify_bit
<< endl;
}
return 1;
}
// FIFO调度算法解决缺页中断
int virtual_memory::FIFO(int pagenum) {
for (int i = 0; i < MAXSIZE; ++i) {
if (s[i].pagenum == pagenum) {
s[i].sign = 1;
for (int j = 0; j < MAXSIEZ_MAIN; ++j) {
if(P[k] == s[j].pagenum){
s[i].main_memory = s[j].main_memory;
s[j].main_memory = 0;
s[j].sign = 0;
if (s[j].modify_bit == 1){
s[j].modify_bit = 0;
}
cout << "调出的页面为: " << s[j].pagenum <<endl;
cout << "调入的页面为: " << s[i].pagenum << endl;
break;
}
}
break;
}
}
P[k] = pagenum;
k = (k+1)%MAXSIZE;
return 1;
}
調用實現代碼:
virtual_memoryDemo.cpp
//
// Created by 86176 on 2022/5/11 0011.
//
#include "virtual_memory.cpp"
#include <iostream>
#include <string>
using namespace std;
// 输入指令操作
int input_operation(Operation &operators){
cout << "请依次输入操作名、页号、字块号" << endl;
cin >> operators.operate >> operators.pagenumber >> operators.unit_number;
return 0;
}
// 测试函数
int main(){
virtual_memory virtualMemory;
virtualMemory.show();
Operation operators;
while(1){
input_operation(operators);
virtualMemory.Find_absolute_address(operators);
virtualMemory.show();
}
return 0;
}
4.驱动调度
Elevator_scheduling.h
//
// Created by 86176 on 2022/5/23 0023.
//
#ifndef VIRTUAL_MEMORYDEMO_CPP_ELEVATOR_SCHEDULING_H
#define VIRTUAL_MEMORYDEMO_CPP_ELEVATOR_SCHEDULING_H
#include <iostream>
#include<string>
using namespace std;
class Elevator_scheduling {
private:
typedef struct request {//请求I/O表
string name;//进程名
int cylinder;//柱面号
int magnetic;//磁道号
int record;//物理记录号
}Request;
int tableNum = 0; // 当前盘号
Request Table[100]; // 创建一张100大小的请求I/O表
Request current; // 当前进程
void InitCurrent(); // 初始化进程
int FindNearest(); // 查找最小距离的编号
void print_io(); // 打印IO表
void PrintProcess(bool direction);// 输出进程
int CylinderJudge(); // 判断是否有与当前柱面号相同的访问者
int CylinderMax(); // 查找比当前柱面号大的访问请求
int CylinderMin(); // 查找比当前柱面号小的访问请求
void PopProcess(int process); // 弹出进程
int Scan(); // 移臂
void Accept(); // 登记进程
void CountTable(); // 记录盘号
public:
Elevator_scheduling();
~Elevator_scheduling(){}
};
#endif //VIRTUAL_MEMORYDEMO_CPP_ELEVATOR_SCHEDULING_H
Elevator_scheduling.cpp
//
// Created by 86176 on 2022/5/23 0023.
//
#include "Elevator_scheduling.h"
#include <iostream>
#include<string>
#include<iomanip>
#include<cmath>
using namespace std;
Elevator_scheduling::Elevator_scheduling() {
float n;
int command=1;
InitCurrent();//初始化当前位置
CountTable();//统计IO请求表中请求数目
while (command == 1) {
cout << "输入在[0,1]区间内的一个随机数!!!" << endl;
cin >> n;
if (n > 0.5) {
Scan();
}
else {
Accept();
}
cout << "继续请按1,退出请按0" << endl;
cin >> command;
}
}
void Elevator_scheduling::Accept() {
int flag = 1;
while (flag == 1) {
cout << "输入:进程名、柱面号、磁道号、物理记录号" << endl;
cin >> Table[tableNum].name >> Table[tableNum].cylinder >> Table[tableNum].magnetic >> Table[tableNum].record;
tableNum++;
cout << "登记成功!继续登记请求按1否则按0" << endl;
cin >> flag;
}
}
int Elevator_scheduling::Scan() {
int process;//选择的进程号
bool direction =1; //方向0=out,1=in,默认移臂方向为向里移
print_io();
if (tableNum == 0) {//无等待访问者
cout << "无等待访问者!!!" << endl;
return 0;
}
else{//有等待访问者
if (CylinderJudge() != -1) {//有与当前柱面号相同的访问者
process = FindNearest();
}
else{//没有与当前柱面号相同的访问者
if (direction == 1) {//移臂方向为向里
process = CylinderMax();
if (process == -1) {//没有比当前柱面号大的访问请求
process = CylinderMin();
direction = 0;
}
}else {//移臂方向为向外
process = CylinderMin();
if (process == -1) {//没有比当前柱面号小的访问请求
process = CylinderMax();
direction = 1;
}
}
}
current = Table[process];
PrintProcess(direction);
PopProcess(process);
}
return 1;
}
void Elevator_scheduling::PopProcess(int process) {
for (int i = process; i < tableNum; i++) {
Table[i] = Table[i + 1];
}
tableNum--;
}
int Elevator_scheduling::CylinderMin() {
int differenceC = 200;//柱面号之差
int t = 8;//最小物理记录
int k;//选择出的最大柱面号
int a;//选择出的最佳请求号
for (int i = 0; i < tableNum; i++) {
if (abs(Table[i].cylinder - current.cylinder) < differenceC && Table[i].cylinder < current.cylinder) {
differenceC = abs(Table[i].cylinder - current.cylinder);
}
k = current.cylinder - differenceC;
}
for (int i = 0; i < tableNum; i++) {
if (Table[i].cylinder == k && Table[i].record < t) {
t = Table[i].record;
a = i;
}
}
if (differenceC == 200) {//没有比当前柱面号小的访问请求
return -1;
}
else {
return a;
}
}
int Elevator_scheduling::CylinderMax() {
int differenceC=200;//柱面号之差
int t = 8;//最小物理记录
int k;//选择出的最小柱面号
int a;//选择出的最佳请求号
for (int i = 0; i < tableNum; i++) {
if (abs(Table[i].cylinder - current.cylinder) < differenceC && Table[i].cylinder > current.cylinder) {
differenceC = Table[i].cylinder - current.cylinder;
}
k = current.cylinder + differenceC;
}
for (int i = 0; i < tableNum; i++) {
if (Table[i].cylinder == k && Table[i].record < t) {
t = Table[i].record;
a = i;
}
}
if (differenceC == 200) {//没有比当前柱面号大的访问请求
return -1;
}
else {
return a;
}
}
int Elevator_scheduling::CylinderJudge() {
for (int i = 0; i < tableNum; i++) {
if (Table[i].cylinder == current.cylinder)
return i;
}
return -1;
}
void Elevator_scheduling::PrintProcess(bool direction) {
string directionStr;
if (direction == 1) {
directionStr = "up";
}else {
directionStr = "down";
}
cout << "------------------------选中的进程信息------------------------" << endl;
cout << "进程名: 柱面号: 物理记录号: 方向:" << endl;
cout << setfill(' ') << setw(6) << current.name << setfill(' ') << setw(15) <<current.cylinder << setfill(' ') << setw(16) << current.record << setfill(' ') << setw(17) << directionStr << endl;
cout << "--------------------------------------------------------------" << endl;
}
void Elevator_scheduling::print_io() {
cout << "--------------------------请求I/O表---------------------------" << endl;
cout << "进程名: 柱面号: 磁道号: 物理记录号:" << endl;
for (int i = 0; i < tableNum; i++) {
cout << setfill(' ') << setw(6) << Table[i].name << setfill(' ') << setw(15) << Table[i].cylinder << setfill(' ') << setw(16) << Table[i].magnetic << setfill(' ') << setw(17) << Table[i].record << endl;
}
cout << "--------------------------------------------------------------" << endl;
}
int Elevator_scheduling::FindNearest() {
int min = 8, k;//最小距离,最小距离的编号
int distance = 8;//当前距离
for (int i = 0; i < tableNum; i++) {
if (Table[i].cylinder == current.cylinder) {
distance = abs(Table[i].record - current.record);
if (distance < min) {
min = distance;
k = i;
}
}
}
return k;
}
void Elevator_scheduling::CountTable() {
int i=0;
while (Table[i].name != ""){
i++;
}
tableNum = i;
}
void Elevator_scheduling::InitCurrent() {
current.name = "初始进程";
current.cylinder = 0;
current.magnetic = 0;
current.record = 0;
//假定表中已经存在的请求
Table[0].name = "A";
Table[0].cylinder = 67;
Table[0].magnetic = 1;
Table[0].record = 6;
Table[1].name = "B";
Table[1].cylinder = 31;
Table[1].magnetic = 15;
Table[1].record = 1;
Table[2].name = "C";
Table[2].cylinder = 16;
Table[2].magnetic = 3;
Table[2].record = 5;
Table[3].name = "D";
Table[3].cylinder = 88;
Table[3].magnetic = 4;
Table[3].record = 2;
Table[4].name = "E";
Table[4].cylinder = 127;
Table[4].magnetic = 17;
Table[4].record = 4;
}
調用實現
Elevator_schedulingDemo.cpp
//
// Created by 86176 on 2022/5/23 0023.
//
#include "Elevator_scheduling.cpp"
int main(){
Elevator_scheduling g;
}
GitHub查看
GitHub查看
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiYDS10UP09zZuBnL0xWdhZWZk1ibvNWavw1cu92Yp9CXr5WaM5GZzN0LcNnbpdWdsB3LcJ3b0lGZlt2YvwFNuEjLyU2chVGblJ3LcxWb0h2Xy9GdpRWZfd2bsJ2LcV2chVGblJ3Lc52YucWbp5GZzN2Lc9CX6MHc0RHaiojIsJye.png)
https://github.com/ITApeDeHao/OperationSystem/tree/master/project