天天看點

作業系統實驗【UJS】作業系統實驗

作業系統實驗

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檢視

作業系統實驗【UJS】作業系統實驗

https://github.com/ITApeDeHao/OperationSystem/tree/master/project

繼續閱讀