精华内容
下载资源
问答
  • C++模拟进程的三状态模型和进程调度(FCFS)性能计算 不多BB 直接上代码 main.cpp文件 //main.cpp #include "Basic_function.h" #include "State_transition.h" //关键词:进程三模型状态模拟 进程调度(FCFS)性能...

    C++模拟进程的三状态模型和进程调度(FCFS)性能计算

    不多BB 直接上代码

    main.cpp文件

    //main.cpp
    #include "Basic_function.h"
    #include "State_transition.h"
    //关键词:进程三模型状态模拟 进程调度(FCFS)性能计算
    using namespace std;
    typedef unsigned int uint;
    
    uint cur_time; //时间线
    uint CPU_size; //几核CPU
    uint IO1_equipment_size; //几个IO1设备
    uint IO2_equipment_size; //几个IO2设备
    double turnover_time_sum; //所有进程周转时间之和
    double weighted_turnover_time_sum; //所有进程带权周转时间之和
    
    vector<PCB> CPU; //处理机
    vector<PCB> IO1_equipment; //IO1设备
    vector<PCB> IO2_equipment; //IO2设备
    vector<PCB> destroy; //待销毁
    queue<PCB> ready_que; //就绪队列
    queue<PCB> block_IO1_que; //请求IO1设备阻塞队列
    queue<PCB> block_IO2_que; //请求IO2设备阻塞队列
    
    
    bool cmp(PCB &a,PCB &b){ //先来先进内存(就绪队列)
        return a.get_arrive_time()<b.get_arrive_time();
    }
    
    void READY_TO_CPU(){
        while(ready_to_CPU());//ready就绪队列里面的进程上处理机运行
        while(scan_CPU()) while(ready_to_CPU()); //扫描CPU 看是否需要有变动(有进程下CPU) 如果有的话继续让ready就绪队列上CPU
        //至于这里为什么在 while()whiel(); 语句前面还需要一个while语句 是因为可能会出现这种情况:
        //“当前的还有空闲的CPU,而ready就绪队列里面又刚好到了新的就绪进程,但是不巧的是没有需要下CPU的进程”
        //BLOCK_QUE_TO_IO函数同理
    }
    
    void BLOCK_QUE_TO_IO(){
        while(block_que_to_IO(1)); //block就绪队列里面的进程上IO1设备进行IO操作
        while(scan_IO_equipment(1)) while(block_que_to_IO(1)); //扫描IO1设备 看是否需要有变动(有进程下IO1设备) 如果有的话继续让block就绪队列上IO1设备
    
        while(block_que_to_IO(2));//block就绪队列里面的进程上IO2设备进行IO操作
        while(scan_IO_equipment(2)) while(block_que_to_IO(2)); //扫描IO2设备 看是否需要有变动(有进程下IO2设备) 如果有的话继续让block就绪队列上IO2设备
    }
    
    int main() { //模拟开始
    
        printf("请输入CPU个数(同时可以跑几个进程):");
        cin>>CPU_size;
    
        printf("请输入分别有几台IO1设备、IO2设备:");
        cin>>IO1_equipment_size>>IO2_equipment_size;
    
        printf("请输入本次模拟的总进程数目:");
        uint num;cin>>num;
    
        vector<PCB> tmp;
        for(uint i=0;i<num;i++) tmp.push_back(createProgress(i));
    
        sort(tmp.begin(),tmp.end(),cmp); //按照到达时间排序
        cur_time=0; //初始化时间线
        turnover_time_sum=weighted_turnover_time_sum=0.0; //初始化 总的周转时间和带权周转时间
        while(tmp.size() || CPU.size() || ready_que.size() || IO1_equipment.size() || IO2_equipment.size() ||block_IO1_que.size() || block_IO2_que.size()){
    
            while(tmp.size() && tmp[0].get_arrive_time()==cur_time){ //有进程到了就从后备队列调入内存(就绪队列)
                PCB &t=tmp[0];
                ready_que.push(t);
                tmp.erase(tmp.begin());
            }
    
            READY_TO_CPU(); //保证:运行完毕的进程下CPU 就绪队列进程上CPU **************1
            BLOCK_QUE_TO_IO(); //保证:IO完毕的进程下IO设备 等待IO的阻塞队列进程上IO ****2
    
            printProgresses(); //打印进程信息
            destroyProgresses(); //销毁进程
    
            cur_time++; //全程序的"key"--时间线推移,只有它才能推动这次模拟在逻辑上的运行!!!
    
            CPU_runProgresses(); //模拟CPU跑运行进程
            ready_wait(); //模拟就绪队列的等待
    
            use_IO_equipment(); //模拟阻塞进程进行IO
            block_wait(); //模拟阻塞队列的等待
    
            READY_TO_CPU(); //保证:运行完毕的进程下CPU 就绪队列进程上CPU **************3
            BLOCK_QUE_TO_IO(); //保证:IO完毕的进程下IO设备 等待IO的阻塞队列进程上IO ****4
    
            //只有保证 1 2 cur_time++ 3 4 这样的顺序才可以做到在“离散的时间点”上实现肉眼所见的“时间连续”
        }
        printProgresses();
        destroyProgresses();
        printf("\n该次模拟的进程平均周转时间 %.2f, 平均带权周转时间 %.2f\n",turnover_time_sum/num,weighted_turnover_time_sum/num);
        //模拟结束
        return 0;
    }
    

    PCB.h文件

    // Created by BingWeiHuang on 2021/4/6.
    // 这里是PCB类的声明
    // PCB.h
    #ifndef SIMPLE_THREE_STATE_SIMULATION_OF_THE_PROCESS_PCB_H
    #define SIMPLE_THREE_STATE_SIMULATION_OF_THE_PROCESS_PCB_H
    #include <iostream>
    #include <queue>
    #include <algorithm>
    #include <string>
    #include <cstdio>
    
    using namespace std;
    typedef unsigned int uint;
    extern uint cur_time;
    extern uint CPU_size;
    extern double turnover_time_sum;
    extern double weighted_turnover_time_sum;
    
    class PCB{
    private:
        uint index; //进程序号
        string name; //进程名
        string state; //进程状态
        uint need_running_time; //预计运行时间
        uint arrive_time; //程序到达时间
        uint running_time; //实际已经运行的时间
        uint end_time; //结束时间
        uint waiting_time; //等待时间
    public:
        bool need_IO1,need_IO2; //是否需要IO1 IO2设备
        uint when_need_IO1,when_need_IO2; //在CPU上运行多少时间之后需要请求IO设备
        uint IO1_time,IO2_time; //最开始设置的需要IO设备多长时间
        uint need_IO1_time,need_IO2_time; //实际上还需要占用IO设备多长时间
        bool have_IO1,have_IO2; //是否正在占用IO设备
    
        uint turnover_time()const;//周转时间
        double weighted_turnover_time()const;//带权周转时间
        void Run();//运行
        void Wait();//等待
        void End();//结束
        void set_state(string new_state);
        uint get_arrive_time()const;
        uint get_running_time()const;
        uint get_need_running_time()const;
        void print()const;
        PCB(uint inde,string nam,string sta,uint need_running_t,uint arrive_t,bool IO1,bool IO2);
    };
    #endif //SIMPLE_THREE_STATE_SIMULATION_OF_THE_PROCESS_PCB_H
    
    

    PCB.cpp文件

    // 这里是PCB类的实现
    // PCB.cpp
    #include "PCB.h"
    extern uint cur_time;
    extern uint CPU_size;
    extern double turnover_time_sum;
    extern double weighted_turnover_time_sum;
    
    extern vector<PCB> CPU; //处理机
    extern queue<PCB> ready_que; //就绪队列
    extern queue<PCB> block_IO1_que; //请求IO1设备阻塞队列
    extern queue<PCB> block_IO2_que; //请求IO2设备阻塞队列
    extern vector<PCB> destroy; //待销毁
    using namespace std;
    
    uint PCB::turnover_time()const{ //周转时间
        return cur_time-arrive_time;
    }
    double PCB::weighted_turnover_time()const{ //带权周转时间
        return turnover_time()*1.0/running_time;
    }
    void PCB::Run(){ //运行
        running_time++;
    }
    void PCB::Wait(){ //等待
        waiting_time++;
    }
    void PCB::End(){ //结束
        end_time=cur_time;
        have_IO1=have_IO2=0;
    }
    void PCB::set_state(string new_state){
        state=new_state;
    }
    uint PCB::get_arrive_time()const{
        return arrive_time;
    }
    uint PCB::get_running_time()const{
        return running_time;
    }
    uint PCB::get_need_running_time()const{
        return need_running_time;
    }
    void PCB::print()const{
        printf("进程%d:\t",index);
        cout<<"|名称:"<<name<<"\t";
        cout<<"|状态:"<<state<<"\t";
        printf("|到达时刻:%4d",arrive_time);
        printf("|预计运行时长:%4d",need_running_time);
        printf("|已运行总时长:%4d",running_time);
        printf("|已等待总时长:%4d|",waiting_time);
        if(state=="block"){
            if(need_IO1 && have_IO1){
                printf("\n\t|已经使用IO1时长:%4d",IO1_time-need_IO1_time);
                printf("|还需要使用时长:%4d|",need_IO1_time);
            }
            else if(need_IO2 && have_IO2){
                printf("\n\t|已经使用IO2时长:%4d",IO2_time-need_IO2_time);
                printf("|还需要使用时长:%4d|",need_IO2_time);
            }
        }
        else if(state=="destroy"){
            printf("\n\t|执行IO的总时长:%4d",turnover_time()-waiting_time-running_time);
            printf("|结束时刻:%4d",end_time);
            printf("|周转时间:%4d",turnover_time());
            printf("|带权周转:%6.2lf|",weighted_turnover_time());
        }
        cout<<endl;
    }
    PCB::PCB(uint inde,string nam,string sta,uint need_running_t,uint arrive_t,bool IO1,bool IO2):
            index(inde),name(nam),state(sta),need_running_time(need_running_t),arrive_time(arrive_t),need_IO1(IO1),need_IO2(IO2){
        running_time=waiting_time=0;
        have_IO1=have_IO2=0;
    }
    

    State_transition.h文件

    // Created by BingWeiHuang on 2021/4/6.
    // 这里是关于状态转换的函数的声明
    // State_transition.h
    #ifndef SIMPLE_THREE_STATE_SIMULATION_OF_THE_PROCESS_STATE_TRANSITION_H
    #define SIMPLE_THREE_STATE_SIMULATION_OF_THE_PROCESS_STATE_TRANSITION_H
    #include "PCB.h"
    using namespace std;
    typedef unsigned int uint;
    extern uint cur_time;
    extern uint CPU_size;
    extern uint IO1_equipment_size;
    extern uint IO2_equipment_size;
    extern double turnover_time_sum;
    extern double weighted_turnover_time_sum;
    
    extern vector<PCB> CPU; //处理机
    extern vector<PCB> IO1_equipment; //IO1设备
    extern vector<PCB> IO2_equipment; //IO2设备
    extern queue<PCB> ready_que; //就绪队列
    extern queue<PCB> block_IO1_que; //请求IO1设备阻塞队列
    extern queue<PCB> block_IO2_que; //请求IO2设备阻塞队列
    extern vector<PCB> destroy; //待销毁
    
    void CPU_to_destroy(int i);//从cpu里面终止进程
    
    
    void CPU_to_block(uint i,uint num);//等待IO 阻塞
    
    void block_to_ready(uint i,uint num);//已经具备所有资源 唤醒
    
    bool ready_to_CPU();//就绪队列上处理机(FCFS)
    
    
    void block_to_destroy(uint i,uint num);//有可能出现IO请求被完成之后已经不需要再运行了,为了方便起见我们直接再写一个函数直接终止。
    
    
    #endif //SIMPLE_THREE_STATE_SIMULATION_OF_THE_PROCESS_STATE_TRANSITION_H
    
    

    State_transition.cpp文件

    // 这里是这里是关于状态转换的函数的实现
    // State_transition.cpp
    #include "State_transition.h"
    
    void CPU_to_destroy(int i){ //从cpu里面终止进程
        PCB &t=CPU[i];
        t.End();
        t.set_state("destroy");
        destroy.push_back(t);
        CPU.erase(CPU.begin()+i);
    }
    
    void CPU_to_block(uint i,uint num){ //等待IO 阻塞
        PCB t=CPU[i];
        t.set_state("block");
        if(num==1){
            block_IO1_que.push(t);
        }
        else if(num==2){
            block_IO2_que.push(t);
        }
        CPU.erase(CPU.begin()+i);
    }
    
    void block_to_ready(uint i,uint num){ //已经具备所有资源 唤醒
        if(num==1){
            PCB &t=IO1_equipment[i];
            t.have_IO1=0;
            t.need_IO1=0;
            t.set_state("ready");
            ready_que.push(t);
            IO1_equipment.erase(IO1_equipment.begin()+i);
        }
        else if(num==2){
            PCB &t=IO2_equipment[i];
            t.have_IO2=0;
            t.need_IO2=0;
            t.set_state("ready");
            ready_que.push(t);
            IO2_equipment.erase(IO2_equipment.begin()+i);
        }
    
    }
    
    bool ready_to_CPU(){ //就绪队列上处理机(FCFS)
        if(CPU.size()==CPU_size || ready_que.empty()) return 0;
        PCB &t=ready_que.front();
        t.set_state("running");
        CPU.push_back(t);
        ready_que.pop();
        return 1;
    }
    
    void block_to_destroy(uint i,uint num){ //有可能出现IO请求被完成之后已经不需要再运行了,直接终止。
        if(num==1){          //因为如果按步骤 阻塞队列->就绪队列->CPU->终止 可能会因为所有CPU都在被占用而无法及时执行完此步骤终止该进程。
            PCB &t=IO1_equipment[i];
            t.End();
            t.set_state("destroy");
            destroy.push_back(t);
            IO1_equipment.erase(IO1_equipment.begin()+i);
        }
        else if(num==2){
            PCB &t=IO2_equipment[i];
            t.End();
            t.set_state("destroy");
            destroy.push_back(t);
            IO2_equipment.erase(IO2_equipment.begin()+i);
        }
    }
    
    

    Basic_function.h文件

    // Created by BingWeiHuang on 2021/4/6.
    // 这里是基本函数的声明
    // Basic_function.h
    #ifndef SIMPLE_THREE_STATE_SIMULATION_OF_THE_PROCESS_BASIC_FUNCTION_H
    #define SIMPLE_THREE_STATE_SIMULATION_OF_THE_PROCESS_BASIC_FUNCTION_H
    #include "PCB.h"
    using namespace std;
    typedef unsigned int uint;
    extern uint cur_time;
    extern uint CPU_size;
    extern uint IO1_equipment_size;
    extern uint IO2_equipment_size;
    extern double turnover_time_sum;
    extern double weighted_turnover_time_sum;
    
    extern vector<PCB> CPU; //处理机
    extern vector<PCB> IO1_equipment; //IO1设备
    extern vector<PCB> IO2_equipment; //IO2设备
    extern queue<PCB> ready_que; //就绪队列
    extern queue<PCB> block_IO1_que; //请求IO1设备阻塞队列
    extern queue<PCB> block_IO2_que; //请求IO2设备阻塞队列
    extern vector<PCB> destroy; //待销毁
    
    bool input_valid(uint need_running_t,uint when,uint time);//检测 ”运行多长时间之后需要IO1设备以及需要多长时间的输入“ 是否合理
    
    PCB createProgress(uint index);//创建进程
    
    void printProgresses();//输出各个进程的情况
    
    bool scan_CPU();//扫描CPU 将该下的进程下CPU
    
    void CPU_runProgresses();//模拟CPU的运行
    
    void ready_wait();//就绪队列每个进程的等待模拟 其实就是waiting_time++
    
    bool scan_IO_equipment(uint num);//扫描IO设备 看看是否有进程使用完毕
    
    void use_IO_equipment();//模拟IO设备的使用 其实就是need_IO1(2)_time--;
    
    void block_wait();//阻塞队列每个进程的等待模拟 其实就是waiting_time++
    
    bool block_que_to_IO(uint num);//给阻塞队列的进程安排IO设备 其实就和就绪队列上CPU类似 只不过这里是没有状态的转换 都是阻塞态
    
    void destroyProgresses();//销毁已经终止的进程
    #endif //SIMPLE_THREE_STATE_SIMULATION_OF_THE_PROCESS_BASIC_FUNCTION_H
    
    

    Basic_function.cpp文件

    // 这里是基本函数的实现
    // Basic_function.cpp
    #include "Basic_function.h"
    #include "State_transition.h"
    
    bool input_valid(uint need_running_t,uint when,uint time){ //检测 ”运行多长时间之后需要IO1设备以及需要多长时间的输入“ 是否合理
        return (need_running_t>=when)&&(time);
    }
    
    PCB createProgress(uint index){ //创建进程
        string name,state="ready";
        uint need_running_t,arrive_t;
        bool IO1,IO2;
        printf("\n进程序号: %d\n",index);
    
        printf("请输入进程名称:");
        cin>>name;
    
        printf("请输入预计运行时间:");
        cin>>need_running_t;
    
        printf("请输入到达时间:");
        cin>>arrive_t;
    
        printf("进程是否需要IO1或IO2设备(1表示需要 0表示不需要):");
        cin>>IO1>>IO2;
    
        PCB res(index,name,state,need_running_t,arrive_t,IO1,IO2);
    
        uint when1,time1,when2,time2;
        if(IO1){
            printf("请输入运行多长时间后需要IO1设备 需要多长时间:");
            cin>>when1>>time1;
            while(!input_valid(need_running_t,when1,time1)){
                cout<<endl<<"输入数据不合理 请重新输入:";
                cin>>when1>>time1;
            }
            res.when_need_IO1=when1;res.IO1_time=res.need_IO1_time=time1;
        }
        if(IO2){
            printf("请输入运行多长时间之后需要IO2设备 需要多长时间:");
            cin>>when2>>time2;
            while(!input_valid(need_running_t,when2,time2) || when1==when2){
                cout<<endl<<"输入数据不合理 请重新输入:";
                cin>>when2>>time2;
            }
            res.when_need_IO2=when2;res.IO2_time=res.need_IO2_time=time2;
        }
        return res;
    }
    
    void printProgresses(){ //输出各个进程的情况
        printf("\n******************************************************************************************\n");
        printf("目前时间: %d\n",cur_time);
    
        printf("\n处理机上有 %d 个进程正在运行:\n",CPU.size());
        for(auto progress:CPU) progress.print();
    
        queue<PCB> tmp=ready_que; //拷贝一个副本进行操作 以免影响到原始的进程队列
        printf("\n就绪队列中存在 %d 个进程:\n",tmp.size());
        while(tmp.size()){
            tmp.front().print();
            tmp.pop();
        }
    
        printf("\nIO1设备上有 %d 个进程正在IO:\n",IO1_equipment.size());
        for(auto progress:IO1_equipment) progress.print();
    
        tmp=block_IO1_que;
        printf("\nIO1阻塞队列中存在 %d 个进程:\n",tmp.size());
        while(tmp.size()){
            tmp.front().print();
            tmp.pop();
        }
    
    
        printf("\nIO2设备上有 %d 个进程正在IO:\n",IO2_equipment.size());
        for(auto progress:IO2_equipment) progress.print();
        tmp=block_IO2_que;
    
        printf("\nIO2阻塞队列中存在 %d 个进程:\n",tmp.size());
        while(tmp.size()){
            tmp.front().print();
            tmp.pop();
        }
    
        printf("\n待销毁 %d 个进程:\n",destroy.size());
        for(auto progress:destroy) progress.print();
    
        cout<<endl;
    }
    
    bool scan_CPU(){ //扫描CPU
        bool f=0;
        for(uint i=0;i<CPU.size();i++){
            PCB &t=CPU[i];
            if(t.need_IO1&&t.when_need_IO1==t.get_running_time()){ //进程到了该IO1的时刻
                CPU_to_block(i,1);
                i--;f=1;
            }
            else if(t.need_IO2&&t.when_need_IO2==t.get_running_time()){ //进程到了该IO2的时刻
                CPU_to_block(i,2);
                i--;f=1;
            }
            else if(t.get_running_time()==t.get_need_running_time()){ //进程达到预计运行时间运行该终止了 不能将该条放在最前面if里面 因为会出现预计运行时间运行完后再需要IO的情况
                CPU_to_destroy(i);
                i--;f=1;
            }
        }
        return f; //是否有进程下CPU了
    }
    
    void CPU_runProgresses(){ //模拟CPU运行
        for(uint i=0;i<CPU.size();i++) CPU[i].Run(); //就是每个进程running_time++
    }
    
    void ready_wait(){ //就绪队列每个进程的等待模拟 其实就是waiting_time++
        if(ready_que.empty()) return ;
        queue<PCB> tmp=ready_que; //因为queue不提供迭代器遍历 所以借助一个tmp副本进行逐个操作
        while(ready_que.size()) ready_que.pop();
        while(tmp.size()){
            tmp.front().Wait();
            ready_que.push(tmp.front());
            tmp.pop();
        }
    }
    
    bool scan_IO_equipment(uint num){
        bool f=0;
        if(num==1){
            for(uint i=0;i<IO1_equipment.size();i++){
                PCB &t=IO1_equipment[i];
                if(t.need_IO1_time==0){
                    if(t.get_running_time()==t.get_need_running_time()){ //出现了IO请求被完成之后已经不需要再运行了,直接终止
                        block_to_destroy(i,1);
                    }
                    else
                        block_to_ready(i,1);
                    f=1;i--;
                }
            }
        }
        else if(num==2){
            for(uint i=0;i<IO2_equipment.size();i++){
                PCB &t=IO2_equipment[i];
                if(t.need_IO2_time==0){
                    if(t.get_running_time()==t.get_need_running_time()){ //出现了IO请求被完成之后已经不需要再运行了,直接终止
                        block_to_destroy(i,2);
                    }
                    else
                        block_to_ready(i,2);
                    f=1;i--;
                }
            }
        }
        return f;
    }
    
    void use_IO_equipment(){
        for(uint i=0;i<IO1_equipment.size();i++){
            IO1_equipment[i].need_IO1_time--;
        }
        for(uint i=0;i<IO2_equipment.size();i++){
            IO2_equipment[i].need_IO2_time--;
        }
    }
    
    void block_wait(){
        queue<PCB> tmp=block_IO1_que;//因为queue不提供迭代器遍历 所以借助一个tmp副本进行逐个操作
        while(block_IO1_que.size()) block_IO1_que.pop();
        while(tmp.size()){ //模拟等待
            tmp.front().Wait();
            block_IO1_que.push(tmp.front());
            tmp.pop();
        }
    
        tmp=block_IO2_que;
        while(block_IO2_que.size()) block_IO2_que.pop();
        while(tmp.size()){ //模拟等待
            tmp.front().Wait();
            block_IO2_que.push(tmp.front());
            tmp.pop();
        }
    }
    
    bool block_que_to_IO(uint num){
        if(num==1){
            if(IO1_equipment.size()==IO1_equipment_size || block_IO1_que.empty()) return 0;
            PCB &t=block_IO1_que.front();
            t.have_IO1=1;
            IO1_equipment.push_back(t);
            block_IO1_que.pop();
            return 1;
        }
        else if(num==2){
            if(IO2_equipment.size()==IO2_equipment_size || block_IO2_que.empty()) return 0;
            PCB &t=block_IO2_que.front();
            t.have_IO2=1;
            IO2_equipment.push_back(t);
            block_IO2_que.pop();
            return 1;
        }
        return 0;
    }
    
    
    void destroyProgresses(){ //销毁已经终止的进程
        for(auto i:destroy){
            turnover_time_sum+=i.turnover_time();
            weighted_turnover_time_sum+=i.weighted_turnover_time();
        }
        destroy.clear();
    }
    
    

    验证:

    在这里插入图片描述
    在这里插入图片描述

    总结:

    这算是实现脑子里面奇奇怪怪的想法?
    反正就瞎写,也不知道思路正不正,但从我个人的验证来看程序应该是没什么大毛病(可能只是没有测试到,就算有也不承认 ,你们也可以试试,试到了悄咪咪告诉我就行,哈哈哈)。
    可能有人就会问了,为什么不用java写?为什么不用py?
    但是我老师曰过:“其实那些个什么java啊、py啊。。。go语言啊什么‘乱七八糟’的语言底层都是C”,所以我选择用C++,嘿嘿嘿。

    (好吧,不装了,摊牌了,其实我就只会写一点点C,其他的语言都不会哇呜呜呜呜呜~)
    其实代码里面的细节还是做的不到位很多地方要整改,而且还有很多需要完善和补充的地方,比如:
    1.进程调度的其他算法(害,我只会FCFS)
    2.优先级,当两个处于相同状态进程同时需要争抢最后一份资源(IO设备、CPU)的时候该怎么处理(此时FCFS不奏效,因为“同时”,这就要涉及到优先级了,太麻烦了太难了 暂时不写)
    3.高级调度(后备队列进入内存)需要考虑(昨天听操作系统老师讲题目才意识到,从后备队列高级调度到就绪队列也是需要进行写算法限制一下的,毕竟实际上内存大小有限。所以上课直接全程神游于我自己写的代码中,到底怎么样新增高级调度的算法可以实现内存大小限制,怎么样又可以解决进程在内存中不能移动的情况的限制,啊…太复杂了,水瓶有限写不来写不来…)
    4.五状态模型
    5.写一个能解放纸笔的程序来解那些个我不想不会 写的题??

    下次接着完善吧,这次对于我来说已经是一场小型的头脑风暴了。(打码两分钟 debug一小时是真的痛苦,太多了,眼睛都花了,第一次独立写这么多的代码。)

    展开全文
  • 三状态进程模型

    千次阅读 2017-11-27 16:45:27
    很容易想到,一个进程可以处于两种状态:运行态和非运行态。在非运行态中,有的进程在等待某些事件完成(如:I/O... 图1:三状态模型 运行态:进程正在运行。非运行态:a. 就绪态:进程获得了除处理器以外所有运行

    很容易想到,一个进程可以处于两种状态:运行态和非运行态。在非运行态中,有的进程在等待某些事件完成(如:I/O设备)后才能执行,称为阻塞或等待态,有的进程运行条件都已经满足,只差 CPU 资源就可以运行,称为就绪态。因此我们引入三状态进程模型。

    三状态进程模型

                  图1:三状态模型

    • 运行态:进程正在运行。
    • 非运行态:a. 就绪态:进程获得了除处理器以外所有运行所需的资源,得到处理器资源即可运行。
                 b. 阻塞态:进程由于等待某一事件的出现而暂停。
    • 新建态:进程正在被创建,内存控制块还没有加入到就绪队列之前的状态。
    • 退出态:进程正在结束,系统在回收资源。

    从进程运行的周期来看,核心的状态是 运行,就绪,阻塞。另外还加入了新建和退出态。

    三种状态之间的转换

    • 新建态  →  就绪态:进程被创建后,放在就绪队列里。
    • 分派(就绪态 → 运行态):OS从就绪队列中选择一个进程运行(调度算法),又被称为调度。
    • 超时(运行态 → 就绪态):为了防止进程独占CPU,OS规定当程序运行时间达到规定最大值(时间片)时,响应中断将其放置到就绪队列中。
    • 等待事件(运行态 → 阻塞态):由于进程请求某种事件(如:I/O设备)而进入阻塞状态。
    • 事件发生(阻塞态 → 就绪态):当某种事件发生时,处于阻塞队列中等待这个事件的所有进程被转换到就绪队列中。
    • 运行态  →  退出态:程序退出。

    注:抢占(运行态 → 就绪态):如果操作系统给某个进程赋予不同的优先级,假设A , B 两个进程,A优先级大于B,且B处于阻塞状态,当进程A运行时,B等待的事件发生了,则将B转为就绪态。由于B优先级大于A, OS将CPU资源分派给进程B,进程A变成就绪态,我们说进程B抢占了进程A。

    模型怎样工作

    • 进程创建后被加入到就绪态。
    • CPU每次从就绪态选择一个优先级最高的进程执行。
    • 当一个正在运行的进程发生以下情况时,被给予不同的处理。
      • 终      止  →   转到退出态
      • 等待事件  →   转到阻塞态
      • 超     时   →   转到就绪态
    • 当某个事件发生时,产生中断,OS将所有处于等待这个事件的进程转换为就绪态。

    可以观察到,操作系统从就绪态选择某个进程执行,再将其放入到阻塞态或就绪态(图2左),如此循环。只有当某个事件发生时,才将事件所对应的阻塞进程转换为就绪态,借接着又去执行循环(图2右)。

                图2:模型工作框图

    通过一个例子来理解:假设有进程A, 在程序运行时有I/O设备访问,访问完成后程序退出。注:调度时OS根据优先级选择进程执行,不是进程A刚从阻塞队列放置到就绪队列,就去执行它,中间有可能执行了很多其他进程。

                          图:进程A执行过程

    三状态进程队列模型

    我们可以用队列实现:由三状态进程模型,可以将就绪态和阻塞态用两个队列实现。如:图 a)单一的阻塞队列。

    多队列的优势:当进程较多时,OS会频繁的遍历队列,例如当某个事件发生时,需要遍历阻塞队列所有的进程,将请求该事件的进程置为就绪态;当调度时,也需要遍历队列选择优先级最高的。因此可以使用多队列,提高运行速度。

    • 一个事件对应一个队列,当事件发生时,直接将该事件队列所有进程放到就绪队列里。
    • 一个优先级对应一个队列,调度时,先执行优先级最高队列里的进程,队列为空时,执行优先级低的。

            图3:多阻塞队列,就绪队列也可以使用多队列。

    声明:以上内容整理自 《操作系统精髓与设计原理(原书第6版)》 参考 学堂在线 操作系统(清华大学)

    本文为作者原创,转载请注明出处。

    展开全文
  • 进程的三模型

    2019-09-21 21:56:59
    模型:在多道程序系统中,进程在处理器上交替运行,状态也不断地发生变化。进程一般有3种基本状态:运行、就绪和阻塞。 (1)运行:当一个进程在处理机上运行时,则称该进程处于运行状态。处于此状态进程的...
    三态模型:在多道程序系统中,进程在处理器上交替运行,状态也不断地发生变化。进程一般有3种基本状态运行、就绪和阻塞
    (1)运行:当一个进程在处理机上运行时,则称该进程处于运行状态。处于此状态的进程的数目小于等于处理器的数目,对于单处理机系统,处于运行状态的进程只有一个。在没有其他进程可以执行时(如所有进程都在阻塞状态),通常会自动执行系统的空闲进程。
    (2)就绪:当一个进程获得了除处理机以外的一切所需资源,一旦得到处理机即可运行,则称此进程处于就绪状态。就绪进程可以按多个优先级来划分队列。例如,当一个进程由于时间片用完而进入就绪状态时,排入低优先级队列;当进程由I/O操作完成而进入就绪状态时,排入高优先级队列。
    (3)阻塞:也称为等待或睡眠状态,一个进程正在等待某一事件发生(例如请求I/O而等待I/O完成等)而暂时停止运行,这时即使把处理机分配给进程也无法运行,故称该进程处于阻塞状态。

    转载于:https://www.cnblogs.com/amiezhang/p/6738459.html

    展开全文
  • 进程状态-模型

    2021-06-02 22:10:32
    为了便于管理进程,一般来说,按进程在执行过程中不同情况至少要定义种不同的进程状态: (1)运行(running)态:进程占有处理器正在运行。 (2)就绪(ready)态:进程具备运行条件,等待系统分配处理器以便运行。...

    一个进程从创建而产生至撤销而消亡的整个生命期间,有时占有处理器执行,有时虽可运行但分不到处理器、有时虽有空闲处理器但因等待某个事件的发生而无法执行,这一切都说明进程和程序不相同,它是活动的且有状态变化的,这可以用一组状态加以刻画。为了便于管理进程,一般来说,按进程在执行过程中的不同情况至少要定义三种不同的进程状态:
    (1)运行(running)态:进程占有处理器正在运行。
    (2)就绪(ready)态:进程具备运行条件,等待系统分配处理器以便运行。
    (3)等待(wait)态:又称为阻塞(blocked)态或睡眠(sleep)态,指进程不具备运行条件,正在等待某个事件的完成。

    展开全文
  • 本篇帖子继续上篇。... 【系统架构设计师】第一章:操作系统(1.1.1—1.1.2) 参考教材: 《系统架构设计师考试全程指导(第二版)》 ...1.2.1 进程的状态 首先我们要搞清楚个东西的区别:程序,进程,.
  • 进程的引入由于早期未配置os的系统和单道批处理系统中程序是顺序执行的,然而这种方式浪费资源、系统资源利用率较低,从而出现了多道批处理系统。内存中可以同时装入多个程序,使其共享资源、并发执行。为了能使程序...
  • 操作系统——进程的三模型

    千次阅读 2019-10-21 10:26:47
    进程的三模型 何谓进程? 进程是一个程序关于某个数据集的一次运行,是系统进行资源分配和调度的基本单位。 从静态角度看,进程实体 = 进程控制块(PCB)+ 程序段 + 数据段。 从动态角度看,进程是可并发运行程序...
  • • Edit 2017-03-20 • Updata 2017-03-20很容易想到,一个进程可以处于两种状态:运行态和非运行态。在非运行态中,有的进程在等待某些事件完成(如...三状态进程模型 图1:三状态模型运行态:进程正在运行。非...
  • 进程的引入 由于早期未配置os的系统和单道批处理系统中程序是顺序执行的,然而这种方式浪费资源、系统资源利用率较低,从而出现了多道批处理系统。内存中可以同时装入多个程序,使其共享资源、并发执行。为了能使...
  • 每个进程在执行过程中,任意时刻当且仅当处于上述状态之一。同时,在一个进程执行过程中,它的状态将会发生改变。引起进程状态转换具体原因如下: (1)运行态一一等待态:等待使用资源或某事件发生,如等待...
  • 操作系统进程状态模型

    千次阅读 2019-02-23 13:22:13
    这三个状态合起来,就是操作系统三状态进程模型”,如下图: 然后我们可能会疑惑,进程难道天生就是就绪态吗?而且进程执行完后又是什么态呢? 实际上,进程还具有创建态和终止态。 创建态:系统已经为该进程...
  • 进程知识点 1.在操作系统中进程是进行系统资源分配、调度和管理的最小单位。...进程的三模型 1.按照进程在执行过程中的不同状况,进程状态可以分为运行态、就绪态、等待态(就绪态)。 2.各形态说明 ...
  • 1. 进程的概念 进程是指一个具有一定独立功能的程序在一个数据集合上的一次动态执行过程。也就是说程序在对数据进行处理的时候,操作系统是如何维护的。 进程的组成 1 进程的特点 动态性:操作系统可动态...
  • 本文为第篇,进程管理之五状态模型,进程在操作系统里边是有多个状态的,本文就是了解进程在操作系统中的多个状态 1、进程的五个状态 创建状态 就绪状态 阻塞状态 执行状态 终止状态 2、进程处于这五种状态时在...
  • 线程:进程的子集,它是进程内部的一个独立的执行单元,一个进程可以同时并发执行多个线程。 2、进程和线程的区别 进程:有独立的内存空间,进程中的数据存放空间是独立的(堆空间和栈空间都独立),进程中至少有...
  • 进程的三种基本状态2. 进程的其他两种状态3. 进程状态的转换五、进程控制六、进程通信七、线程的概念八、线程的实现方式1. 用户级线程2. 内核级线程3. 两种实现方式的结合九、多线程模型1. 多对一模型2. 一对一模型...
  • 运行态:该进程正在执行;就绪态:进程做好了准备,只要有机会就开始执行;阻塞态:进程在某些事件发生前不能执行,如I/O 操作完成;新建态:刚刚创建的进程,操作系统还没有把它加入到可执行...进程的三态转换 ...
  • 文章目录一、进程的描述进程(processes)的定义进程的组成进程与程序进程与程序的联系进程与程序的区别进程的特点进程控制结构进程控制块PCB包含大信息PCB的组织方式二、进程的状态进程的生命期管理进程创建进程...
  • [进程]进程的状态转换

    千次阅读 2013-04-28 18:57:58
    进程的三模型 按进程在执行过程中的不同情况至少要定义三种状态: 运行(running)态:进程占有处理器正在运行的状态。 进程已获得CPU,其程序正在执行。在单处理机系统中,只有一个进程处于执行状态; 在多...
  • 进程线程模型

    2018-11-03 17:01:04
    文章目录进程的定义进程控制块PCB进程状态及状态转换进程的三种基本状态三状态模型及状态转换进程的其它状态进程的五状态模型进程队列进程控制进程的创建进程的撤销进程阻塞上下文切换线程的定义线程机制的实现用户...
  • 进程的状态转换

    2019-04-01 13:33:54
    1.1进程的三模型 按进程在执行过程中的不同情况至少要定义三种状态: 运行(running)态:进程占有处理器正在运行的状态。 进程已获得CPU,其程序正在执行。在单处理机系统中,只有一个进程处于执行状态; 在多...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 814
精华内容 325
关键字:

进程的三状态模型