作業系統實驗
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