IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 操作系统课程设计 -> 正文阅读

[系统运维]操作系统课程设计

一、时间片轮转法调度

假定系统有5个进程,每个进程用一个PCB来代表。PCB的结构为:

·进程名——如Q1~Q5。

·指针——把5个进程连成队列,用指针指出下一个进程PCB的首地址。

·要求运行时间——假设进程需要运行的时间单位数。

·已运行时间——进程已运行的时间单位数,初始值为0。

·状态——假设两种状态,就绪和结束,用R表示就绪,用E表示结束。初始状态都为就绪状态。

(2) 运行之前,为每个进程确定它的“要求运行时间”。通过键盘输入这些参数。

(3) 把5个进程按顺序排成循环队列,用指针指出队列连接情况。用一个标志单元记录轮到运行的进程。处理器调度总是选择标志单元指示的进程运行,对所指的进程,将其“已运行时间”加1。

(4) 进程运行一次后,若“要求运行时间”等于“已运行时间”,则将状态改为“结束”,退出队列,否则将继续轮转。

(5) 若就绪队列为空,结束,否则转到(3)重复。

#include <iostream>
#include <string>
using namespace std;

class PCB {
public:
    string name;//进程名
    int runningtime;//要求运行时间
    PCB* next;//下个进程块
    int elapsedtime;//已运行时间
    string state = "R";//状态
    PCB(string n, int t);
};
PCB::PCB(string n, int t) {
    name = n;
    runningtime = t;
}
int main()
{
    int rt[5];
    cout << "请依次输入五个进程的要求运行时间" << endl;
    cin >> rt[0] >> rt[1] >> rt[2] >> rt[3] >> rt[4];
    PCB Q1("Q1", rt[0]);
    PCB Q2("Q2", rt[1]);
    PCB Q3("Q3", rt[2]);
    PCB Q4("Q4", rt[3]);
    PCB Q5("Q5", rt[4]);
    Q1.next = &Q2;//默认顺序
    Q2.next = &Q3;
    Q3.next = &Q4;
    Q4.next = &Q5;
    Q5.next = &Q1;
    PCB* runningPcb;//当前运行的进程;
    runningPcb = &Q1;
    
    while (Q1.state == "R" || Q2.state == "R" || Q3.state == "R" || Q4.state == "R" || Q5.state == "R") {
        if (runningPcb->state == "E") {
            runningPcb = runningPcb->next; continue;
        }
        cout << "正在运行进程" << runningPcb->name << ",该进程要求运行时间为" << runningPcb->runningtime << ",已运行时间为" << runningPcb->elapsedtime << endl;
        PCB* checkPcb = runningPcb->next;//检查指针遍历全部就绪进程输出进程情况
        while (runningPcb != checkPcb) {
            if (checkPcb->state == "R") {
                cout << "等待的就绪进程" << checkPcb->name << ",该进程要求运行时间为" << checkPcb->runningtime << ",已运行时间为" << checkPcb->elapsedtime << endl;
            }
            checkPcb = checkPcb->next;
        }
        runningPcb->elapsedtime++;
        if (runningPcb->elapsedtime == runningPcb->runningtime) {//判定进程是否运行结束
            runningPcb->state = "E";
        }
        runningPcb = runningPcb->next;
        cout << endl;
    }
}

二、可变分区管理方式下采用首次适应算法实现主存分配和回收

(1) 可变分区方式是按作业需要的主存空间大小来分割分区的。当要装入一个作业时,根据作业需要的主存容量查看是否有足够的空闲空间,若有,则按需分配,否则,作业无法装入。假定内存大小为128K,空闲区说明表格式为:

·分区号——表示是第几个空闲分区;

·起始地址——指出空闲区的起始地址;

·长度——一个连续空闲区的长度;

(2) 采用首次适应算法分配回收内存空间。运行时,输入一系列分配请求和回

收请求。

using System;
using System.Collections.Generic;

namespace FirstFit
{
    public class zone 
    {
        public bool isfree=true;
        public int freeid;
        public int startaddress;
        public int size;
        public zone(int sa,int s)
        {
            startaddress = sa;
            size = s;
        }
    }

    class Program
    {
        static void Allocate(List<zone> listz,int s)//内存申请
        {
            bool isok = false;
            for(int i=0; i< listz.Count; i++)
            {

                if (listz[i].isfree) {
                    
                    if (listz[i].size >= s)
                    {
                        listz[i].isfree = false;
                        listz.Insert(i + 1, new zone(listz[i].startaddress + s, listz[i].size - s));
                        if (listz[i+1].size == 0) { listz.Remove(listz[i+1]); }
                        listz[i].size = s;
                        isok = true;
                        break;
                    }
                }
                
            }if (!isok) Console.WriteLine("内存不够!申请空间失败!");
        }
        static void Reclaim(List<zone> listz, int sa)//内存的回收
        {
            bool isok = false;
            for (int i = 0; i < listz.Count; i++)
            {
                if (listz[i].startaddress == sa) {                     
                    if (listz[i].isfree == false)
                    {
                    listz[i].isfree = true;
                    isok = true;
                    if (i+1<listz.Count&& listz[i +1].isfree == true) {
                        listz[i].size += listz[i+1].size;
                        
                        listz.Remove(listz[i+1]);
                    }
                    if (i - 1 >= 0 && listz[i - 1].isfree == true) {
                        listz[i - 1].size += listz[i].size;
                        listz.Remove(listz[i]);
                    }
                    
                    break;
                    }
                    
                }
            }
            if (!isok) Console.WriteLine("地址错误!回收失败!");
        }
        static void display(List<zone> listz) {
            int j = 1;
            for (int i = 0; i < listz.Count; i++)
            {
                if (listz[i].isfree) { listz[i].freeid = j; j++; 
                System.Console.WriteLine($"分区号:{listz[i].freeid}  起始地址:{listz[i].startaddress}    长度:{listz[i].size}");
                }
            }
        }
        static void Main(string[] args)
        {
            Console.WriteLine("2");
            List<zone> lz = new List<zone>();
            lz.Add(new zone(0, 128));
            display(lz);
            
            string str= "";
            Console.WriteLine("请输入一系列分配请求和回收请求(如10代表请求分配10大小的内存,-10代表回收起始地址为10的分区):");
            while (str!=null)
            {
                 str= "";
                str = Console.ReadLine();
                int i = int.Parse(str);
                if (i > 0) {
                    Allocate(lz, i);
                    Console.WriteLine($"分配了大小为{i}的空间之后的空闲区情况为:");
                }
                if (i <= 0)
                {
                    i = 0-i;
                    Reclaim(lz, i);
                    Console.WriteLine($"回收了起始地址为{i}的分区之后的空闲区情况为:");
                }
                display(lz);
            }
        }
    }
}

三、用位示图管理磁盘存储空间

1) 为了提高磁盘存储空间的利用率,可在磁盘上组织成链接文件、索引文件,这类文件可以把逻辑记录存放在不连续的存储空间。为了表示哪些磁盘空间已被占用,哪些磁盘空间是空闲的,可用位示图来指出。位示图由若干字节构成,每一位与磁盘上的一块对应,“1”状态表示相应块已占用,“0”状态表示该块为空闲。位示图的形式与实习二中的位示图一样,但要注意,对于主存储空间和磁盘存储空间应该用不同的位示图来管理,绝不可混用。

(2) 申请一块磁盘空间时,由分配程序查位示图,找出一个为“0”的位,计算出这一位对应块的磁盘物理地址,且把该位置成占用状态“1”。假设现在有一个盘组共8个柱面,每个柱面有2个磁道(盘面),每个磁道分成4个物理记录。那么,当在位示图中找到某一字节的某一位为“0”时,这个空闲块对应的磁盘物理地址为:

柱面号=字节号

磁道号= 位数 / 4

物理记录号= 位数 % 4

(3) 归还一块磁盘空间时,由回收程序根据归还的磁盘物理地址计算出归还块在位示图中的对应位,把该位置成“0”。按照(2)中假设的盘组,归还块在位示图中的位置计算如下:

字节号=柱面号

位数=磁道号?4+物理记录号

(4) 设计申请磁盘空间和归还磁盘空间的程序。

#include <iostream>
using namespace std;

void Assign(int map[8][8])//分配
{
    int c = 0;
    int t = 0;
    int p = 0;
    cout << "你要申请哪一块磁盘空间啊?:"<<endl;
    int i;
    int j;
    cout << "输入你要申请的空间的位置(第几行第几列的空间)" << endl;
    cin >> i;
    cin >> j;
    i--;
    j--;
    if (map[i][j] == 0 ) {
        c = i;
        t = j / 4;
        p = j % 4;
        map[i][j] = 1;
        cout << "申请成功:柱面号为" << c << ",磁道号为 " << t << ",物理记录号为 " << p << endl;
    }
    else {
        cout << "申请失败,该空间已满。" << endl;
    }
    
        
}

void Recovery(int map[8][8])//归还空间
{
    int c, t, p;
    cout << "请输入你想回收的物理地址:柱面号、磁道号、物理记录号" << endl;
    cin >> c >> t >> p;
    int i = c;
    int j = t * 4 + p;

    if (0<=i&&i<=7&&0<=j&&j<=7)
    {
        if (map[i][j] == 1) {
            map[i][j] = 0;
            cout << "归还空间成功!字节号为 " << i << "位数为 " << j << endl;

        }
        else {
            cout << "归还空间失败!该空间未被占用!" << endl;
        }
    }
    else {
        cout << "归还空间失败!输入的物理地址错误!" << endl;
    }
}

void Print(int map[8][8])
{
    cout << "-------磁盘存储存储位示图-------" << endl;
    for (int i = 0; i < 8; i++)
    {
        cout << "\t    ";
        for (int j = 0; j < 8; j++)
        {
            cout << map[i][j];
        }
        cout << endl;
    }
    cout << endl;
    cout << endl;
}
int main()
{
    int BitMap[8][8];
    for (int i = 0; i < 8; i++)//位示图初始化
    {
        for (int j = 0; j < 8; j++)
            BitMap[i][j] = 0;
    }
    cout << "学号: 姓名:"<<endl;
    Print(BitMap);
    while (true)
    {
        int choice = 0;
        cout << "输入你要执行的操作: 1(分配) 2(回收) " << endl;
        cin >> choice;
        if (choice == 1)
            Assign(BitMap);
        else if (choice == 2)
            Recovery(BitMap);
        Print(BitMap);
    }
    return 0;
}

四、利用fork()系统调用创建进程。

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
    int pid[3];
    int a = 0;
    while (a<3) {
    printf("当前进程id为%d,父进程为%d   a:%d,接下来准备创建进程\n", getpid(), getppid(), a);
    pid[a] = fork();
    a++;
    }
    printf("当前进程id为%d,父进程为%d   a:%d\n", getpid(), getppid(), a);
    sleep(100);
    return 0;
}

五、模拟P、V操作实现同步机构,且用P、V操作解决生产者—消费者问题

#include <iostream>
using namespace std;
using std::rand;

char B[10];//缓冲区
int IN=0, OUT=0;//插入删除指针
class Process {
public :
    string name;
    bool isConsumer;
    char product;
    string state="ready";
    int breakpoint=-1;
    Process(string n,bool is) {
        name = n; isConsumer = is;
    }
Process() {
        name = "Undefined";
    }
};
Process p1("生产者1", false);
Process p2("生产者2", false);
Process c1("消费者1", true);
Process c2("消费者2", true);
struct SQType
{
    Process* i[100];
    int head = 0;
    int rear = 0;
};
struct semaphore {
    int count;
    string name;
    SQType sq;
};
semaphore Empty = { 10 ,"empty"};
semaphore full = { 0 ,"full"};
SQType ready;

void InSQType(semaphore& s,Process &p)
{
    if (s.name == "empty") {
        cout << p.name << "缓冲区满,"<<p.name<<"进程阻塞移入等待队列" << endl;
    }
    if (s.name == "full") {
        cout << p.name << "缓冲区空," << p.name << "进程阻塞移入等待队列" << endl;
    }
    if (s.sq.head == 100)
    {
        cout << "队列已满!操作失败!" << endl;
    }
    else
    {
        s.sq.i[s.sq.head] = &p;      //将进程移入等待队列
        p.state = "wait原因是"+s.name;
        s.sq.head++;
    }
}
void OutSQType(semaphore& s,Process &p) {
    if (s.name == "empty") {
        cout << "有产品了!," << s.sq.i[s.sq.rear]->name  << "进程就绪" << endl;
    }
    if (s.name == "full") {
        cout << "有空间了!," << s.sq.i[s.sq.rear]->name << "进程就绪" << endl;
    }

    if (s.sq.rear == 100)
    {
        cout << "队列已空!操作失败!" << endl;
    }
    else
    {
        if (ready.head == 100)
        {
            cout << "就绪队列已满!操作失败!" << endl;
        }
        else {
            ready.i[ready.head] = s.sq.i[s.sq.rear];      //将等待队列中的队尾进程移进就绪队列
            s.sq.i[s.sq.rear]->state = "ready";

            ready.head++;
            s.sq.rear++;
        }

    }
}
void W(semaphore& s,Process &p) {
    if (s.name=="empty") {
        cout << p.name<<"试图生产但发现缓冲区满了" << endl;
    }
    if (s.name == "full") {
        cout << p.name << "试图消费但发现缓冲区空了" << endl;
    }
    
    InSQType(s,p);
}
void P(semaphore& s,Process &p) {
    s.count--;
    if (s.count < 0) {
        W(s,p);
        
    }
}
void R(semaphore& s,Process &p) {
    

    OutSQType(s,p);
}
void V(semaphore& s,Process &p) {
    s.count++;
    if (s.count <= 0) {
        R(s,p);
    }
}
void display() {
    cout << endl<< "此时生产者1" << p1.state << endl;
cout << "此时生产者2" << p2.state << endl;
cout << "此时消费者1" << c1.state << endl;
cout << "此时消费者2" << c2.state << endl;
cout << "缓冲区情况:" << endl;
for (int i = 0; i<10; i++) { cout << B[i]<<", "; }
cout <<endl<< "缓冲区插入指针为:" << IN<<endl;
cout << "缓冲区删除指针为:" << OUT<<endl;
}
void dispatch(Process &p){//处理机调度
    p.breakpoint++;if(p.breakpoint!=4)p.state = "run";
    display();
    if (!p.isConsumer) {
        switch (p.breakpoint) {
        case 0:
            p.product = 'A' + rand() % (('Z' + 1) - 'A'); 
            cout << p.name << "生产了一个" << p.product  << endl; 
            p.state = "ready";
            break;
        case 1:
            p.state = "ready";
            cout << p.name << "对empty进行P原语操作" <<Empty.count<< endl;
            P(Empty, p); 
            break;
        case 2:p.state = "ready"; cout << p.name << "放入了" << p.product << "到缓冲区" << endl;
            B[IN] = p.product;
            IN = (1 + IN) % 10; 
             break;
        case 3:p.state = "ready";
            cout << p.name << "对full进行V原语操作" <<full.count<< endl; 
            V(full, p);
        case 4:p.state = "ready";
            p.breakpoint = -1; cout << p.name << "进程执行结束但又要准备重新工作" << endl; break;
        }
    }
    if (p.isConsumer) {
        switch (p.breakpoint) {
        case 0:p.state = "ready";
            cout << p.name << "对full进行P原语操作" <<full.count<< endl;
            P(full, p); break;
        case 1:p.state = "ready"; 
            p.product = B[OUT];
            B[OUT] = ' ';
            cout << p.name << "从缓冲区取出了一个" << p.product << endl;
             OUT = (1 + OUT) % 10; break;
        case 2:p.state = "ready"; 
            cout << p.name << "对empty进行V原语操作" <<Empty.count<< endl;
            V(Empty, p); break;
        case 3:cout << p.name << "从缓冲区消费了一个" << p.product << endl;
            cout << p.name << "进程执行结束" << endl;
            p.state = "ready";
             break;
        case 4:p.state = "ready";
            p.breakpoint = -1; cout << p.name << "进程执行结束但又要准备重新工作" << endl; break;
        }
    }

}
void random() {
    if (ready.head == ready.rear) {
        switch (rand()%4)
        {
        case 0:if (p1.state == "ready")dispatch(p1); break;
        case 1:if (p2.state == "ready")dispatch(p2); break;
        case 2:if (c1.state == "ready")dispatch(c1); break;
        case 3:if (c2.state == "ready")dispatch(c2); break;
        }
    
    }
    else {
        dispatch(*ready.i[ready.rear]);
        ready.rear++;
    }

}
int main()
{
    
display();
    if (ready.head == ready.rear) {
        for (int i=0; i < 200; i++) {

            random();
            }

    }
    

}

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-07-14 23:19:00  更:2021-07-14 23:20:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 11:06:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计