天天看点

操作系统实验【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

继续阅读