操作系统模拟之地址转换算法。
文件共3份,其中1份cpp,2份.h,代码如下:
main.cpp
#include "init.h"int main()
{printf("欢迎进入演示系统!\n");printf("\n现在需要对进程数据初始化\n");printf("通过键盘输入请输入1\n");printf("通过构造函数直接生成请输入2\n");int num_initialize;scanf("%d", &num_initialize);printf("\n");node process;if(num_initialize == 1){printf("请输入进程的数量:\n");int process_number;scanf("%d", &process_number);if(process_number > 0)process.set(process_number);}else if(num_initialize != 2)printf("您的输入有误!\n");process.act();printf("\n感谢您的使用,下次再见!\n");return 0;
}
init.h
#include<bits/stdc++.h>
using namespace std;
class node{public:int number; vector<string> name;vector<int> arrive_time;vector<int> serve_time;vector<int> priority;vector<int> begin_time;vector<int> end_time;vector<int> round_time;vector<double> weighted_round_time;vector<string> path;public:node();void set(int num);void act();void process_print();void alo_fcfs();void alo_sjp();void alo_pri1();void alo_pri2();void alo_piece(int num);
};node::node()
{system("cls");printf("开始初始化进程数据\n");number = 5;string s[5] = {"A","B","C","D","E"};int arrive[5] = {0,1,2,3,4};int serve[5] = {4,3,5,2,4};int pri[5] = {4,2,3,5,1};for(int i = 0; i < number; i++){name.push_back(s[i]);arrive_time.push_back(arrive[i]);serve_time.push_back(serve[i]);priority.push_back(pri[i]);}printf("进程数据初始化完成!\n");
}void node::set(int num)
{number = num;name.clear();arrive_time.clear();serve_time.clear();priority.clear();for(int i = 1; i <= num; i++){printf("\n现在输入第%d个进程的数据\n", i);printf("请依次输入进程名、到达时间、服务时间和静态优先权:\n");string process_name;int time_arrive, time_serve, process_priority;cin >> process_name;cin >> time_arrive >> time_serve >> process_priority);name.push_back(process_name);arrive_time.push_back(time_arrive);serve_time.push_back(time_serve);priority.push_back(process_priority);}system("cls");printf("进程数据录入完成!\n\n");
}void node::act()
{while(1){begin_time.clear();end_time.clear();round_time.clear();weighted_round_time.clear();printf("\n请按回车键继续!\n");getchar();getchar();system("cls"); printf("FCFS算法请输入1\n");printf("SJ(P)F算法请输入2\n");printf("优先权算法请输入3\n");printf("时间片轮转算法请输入4\n");printf("退出程序请输入0\n\n"); printf("请选择相应的算法:\n");int choice;scanf("%d", &choice);if(choice == 0)break;else if(choice == 1)alo_fcfs();else if(choice == 2)alo_sjp();else if(choice == 3){printf("\n非抢占优先权算法请输入1\n");printf("抢占优先权算法请输入2\n");int choice_pri;scanf("%d", &choice_pri);if(choice_pri == 1)alo_pri1();else if(choice_pri == 2)alo_pri2();elseprintf("您的输入有误!\n"); }else if(choice == 4){printf("请输入时间片Q的大小:\n");int Q_size;scanf("%d", &Q_size);alo_piece(Q_size);}process_print();}
}void node::process_print()
{for(int i = 0; i < number; i++){round_time.push_back(end_time[i] - arrive_time[i]);weighted_round_time.push_back(1.0 * round_time[i] / serve_time[i]);}system("cls");printf("现在输出进程规划:\n");printf("进程名 到达时间 服务时间 开始时间 完成时间 周转时间 带权周转时间\n");for(int i = 0; i < number; i++){cout << " " << name[i];printf("%8d%9d%9d%10d%9d%12.1f\n", arrive_time[i], serve_time[i], begin_time[i], end_time[i], round_time[i], weighted_round_time[i]);}double res1 = 0.0, res2 = 0.0;for(int i = 0; i < number; i++){res1 += round_time[i];res2 += weighted_round_time[i];}res1 = 1.0 * res1 / number;res2 = 1.0 * res2 / number;printf("平均 %44.1f %10.1f\n\n", res1, res2);printf("轮转顺序为:");for(int i = 0; i < path.size(); i++){if(i > 0)printf("-");cout << path[i];} printf("\n");path.clear();
}void node::alo_fcfs()
{int vis[1005] = {0};int bg[1005] = {0};int finished = 0, nowtime = 0;while(finished < number){int u = -1, mind = 0x3f3f3f3f;for(int i = 0; i < number; i++){if(vis[i] == 0 && arrive_time[i] < mind && nowtime >= arrive_time[i]){mind = arrive_time[i];u = i;} }if(u == -1)break;bg[u] = nowtime;nowtime += serve_time[u];for(int k = 0; k < serve_time[u]; k++)path.push_back(name[u]);vis[u] = nowtime;}for(int i = 0; i < number; i++){begin_time.push_back(bg[i]);end_time.push_back(vis[i]);}
}void node::alo_sjp()
{int vis[1005] = {0};int bg[1005] = {0};int finished = 0, nowtime = 0;while(finished < number){int u = -1, mind = 0x3f3f3f3f;for(int i = 0; i < number; i++){if(vis[i] == 0 && serve_time[i] < mind && nowtime >= arrive_time[i]){mind = serve_time[i];u = i;} }if(u == -1)break;bg[u] = nowtime;for(int k = 0; k < serve_time[u]; k++)path.push_back(name[u]);nowtime += serve_time[u];finished++;vis[u] = nowtime;}for(int i = 0; i < number; i++){begin_time.push_back(bg[i]);end_time.push_back(vis[i]);}
}void node::alo_pri1()
{int vis[1005] = {0};int bg[1005] = {0};int finished = 0, nowtime = 0;while(finished < number){int u = -1, mind = 0x3f3f3f3f;for(int i = 0; i < number; i++){if(vis[i] == 0 && priority[i] < mind && nowtime >= arrive_time[i]){mind = priority[i];u = i;} }if(u == -1)break;bg[u] = nowtime;for(int k = 0; k < serve_time[u]; k++)path.push_back(name[u]);nowtime += serve_time[u];vis[u] = nowtime;}for(int i = 0; i < number; i++){begin_time.push_back(bg[i]);end_time.push_back(vis[i]);}
}void node::alo_pri2()
{int vis[1005] = {0};int bg[1005] = {0};memset(bg, -1, sizeof(bg));int have[1005] = {0};int finished = 0, nowtime = 0;while(finished < number){int u = -1, mind = 0x3f3f3f3f;for(int i = 0; i < number; i++){if(have[i] < serve_time[i] && priority[i] < mind && nowtime >= arrive_time[i]){mind = priority[i];u = i;} }if(u == -1)break;if(bg[u] == -1)bg[u] = nowtime;nowtime ++;path.push_back(name[u]);have[u] ++;if(have[u] == serve_time[u]){vis[u] = nowtime;finished ++;}}for(int i = 0; i < number; i++){begin_time.push_back(bg[i]);end_time.push_back(vis[i]);}
}void node::alo_piece(int num)
{vector<string> str;int all_time = 0;int have[1005];for(int i = 0; i < number; i++){have[i] = serve_time[i];all_time += serve_time[i];}int nowtime = 0;int now = 0;while(nowtime < all_time){int t = now % number;for(int w = 0; w < num; w++){if(have[t] > 0 && nowtime >= arrive_time[t]){str.push_back(name[t]);nowtime ++;have[t] --;}}now++;}int len = str.size();for(int i = 0; i < number; i++){for(int j = len-1; j >= 0; j--){if(str[j] == name[i]){end_time.push_back(j+1);break;}}for(int i = 0; i < number; i++){for(int j = 0; j < len; j++){if(str[j] == name[i]){begin_time.push_back(j);break;}}}path = str;
}
page.h
#include <bits/stdc++.h>
using namespace std;class pages{public:int page_size;int page_number;vector<int> v;public:pages();void data_ini_random();void data_ini_write();void print_data();void data_cal();bool data_check();
}; pages::pages()
{int menu_choice;bool data_flag = false; while(!data_flag){system("cls");printf("你选择的是分页方式\n");printf("请选择数据初始化的方式:\n");printf("选择随机生成请输入0\n");printf("选择手动输入请输入1\n");scanf("%d", &menu_choice);if(menu_choice == 0){data_ini_random();if(!data_check()){printf("\n随机生成的数据有误!\n");printf("\n按任意键重新初始化数据:\n");getchar();getchar();}elsedata_flag = true;} else if(menu_choice == 1){data_ini_write();if(data_check())data_flag = true;}elseprintf("您的输入有误,请重新输入!\n");}printf("\n您的数据初始化成功!\n");
}void pages::data_ini_random()
{system("cls");printf("现在开始随机数据初始化:\n");v.clear();int size[3] = {1,2,4};srand(unsigned(time(NULL)));page_size = size[rand()%3];printf("\n请输入页表项个数:\n");scanf("%d", &page_number);for(int i = 0; i < page_number; i++)v.push_back(rand()%100);
}void pages::data_ini_write()
{system("cls");printf("现在开始数据初始化:\n");v.clear();printf("\n请输入每页大小:");scanf("%d", &page_size);printf("\n请输入页表项个数:\n");scanf("%d", &page_number);int temp_id; bool input_flag;for(int i = 0; i < page_number; i++){while(1){printf("\n现在请输入第%d个页号对应的块号:\n", i);scanf("%d", &temp_id);if(find(v.begin(), v.end(), temp_id) >= v.end()){v.push_back(temp_id);break;}else{printf("您输入的块号有误!\n");int same_id;for(int j = 0; j < v.size(); j++)if(v[j] == temp_id){same_id = j;break;}printf("与第%d号页面输入的块号重复\n", same_id);printf("请重新输入第%d号页面对应的块号!\n", i);}}}
}void pages::print_data()
{printf("\n您选择了分页方式,输入的数据如下:\n");printf("每页大小%dK,页表为:\n", page_size); printf("页号 块号\n");for(int i = 0; i < page_number; i++)printf("%2d %8d\n", i, v[i]);printf("\n请输入任意键继续:\n");getchar();getchar();
}void pages::data_cal()
{system("cls");printf("\n请开始你的表演!\n");printf("请输入逻辑地址:\n");int temp;bool input_flag = false;while(!input_flag){scanf("%d", &temp);if(temp <= (page_number * page_size * 1024))input_flag = true;elseprintf("您的输入超出地址的最大范围,请重新输入!\n");} printf("\n您选择了分页方式,输入的逻辑地址为%d\n", temp);int temp_page = temp / (page_size*1024);int delta = temp % (page_size*1024);printf("其对应的页号为%d,页偏移为%d\n", temp_page, delta);printf("该地址对应的块号为%d,块偏移为%d,物理地址为%d", v[temp_page], delta, page_size*v[temp_page]*1024 + delta);printf("\n按任意键继续:\n");getchar();getchar();
}bool pages::data_check()
{set<int> s;for(int i = 0; i < page_number; i++)s.insert(v[i]);if(s.size() == page_number)return true;else return false;
}