操作系统实验--存储管理

设计要求

·模拟一个虚拟内存;
·虚拟内存采用页式管理方式,页面大小为4k;
·在内存中申请一个10MB的大空间,将它模拟成主存储器;
·在硬盘上建立一个文件,将它模拟成交换区;
·实现虚拟内存管理中的内存分配、回收和内外存交换;
·实现内存管理的数据结构;
·提供一个界面,该界面可以显示自由空间、已分配空间的信息。
·置换算法采用FIFO,LRU,OPT,时钟算法,改进时钟算法。
·实现页表、请求表和空闲页面链。

主程序

(1):初始化
内存块初始化;页表初始化;
(2):进程及访问页面输入
用户交互方式输入;从文件读入;动态随机生成;
(3):置换算法选择
用户交互方式输入;系统自动轮流选择多种置换算法;
(4):分支模块
根据用户选择的算法调用算法对应函数模块;
(5):结果显示模块
采用图形化方式显示内存分配及页面置换结果;


//
// ·模拟一个虚拟内存;
// ·虚拟内存采用页式管理方式,页面大小为4k;
// ·在内存中申请一个10MB的大空间,将它模拟成主存储器;
// ·在硬盘上建立一个文件,将它模拟成交换区;
//        用文件模拟对换区,可以将从内存换出的内容写入外存中的这个文件
// ·实现虚拟内存管理中的内存分配、回收和内外存交换;
// ·实现内存管理的数据结构;
// ·提供一个界面,该界面可以显示自由空间、已分配空间的信息。
// ·置换算法采用FIFO,LRU,OPT,时钟算法,改进时钟算法。
// ·实现页表、请求表和空闲页面链。
//


#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#define DEFAULT_MEM_SIZE 1024*10
/* 内存分配算法 */
// #define MA_fifo 1
// #define MA_lru 2
// #define MA_opt 3
// #define MA_clock 4
// #define MA_iclock 5
using namespace std;

const int max_memBlock = (1<<8)*10;     // 4K一个页面,故共(1<<8)个

// 内存块
struct memBlock_type{
    int stand;          // 占用标志
    int processNum;     // 当前是哪个进程使用
    int pageTime;       // 页面调入时间或顺序
    int usedTime;       // 最近使用的时间
    // struct memBlock *next;
}memBlock[max_memBlock + 5];

// 页表项
struct pagTab_type{
    int inMem;      // 是否在内存
    int logNum;     // 逻辑页号
    int memNum;     // 物理块编号
    int used;       // 访问标记(用于clock算法)
    int changed;        // 修改标记(用于改进型clock)
    int exStorNum;      // 在外存中的页编号
};

// 请求表
struct request_type{
    int reNum;          // 请求进程编号
    int pagCnt;         // 请求进程页数
    int memCnt;         // 请求进程分配内存数
    int exMemStr;       // 外存起始块
    vector<int> readIn;     // 进程页面读入队列
};
vector<request_type*> request_vec;

// 空闲页面链
struct free_pag{
    int stand;
};

// 当前进程
struct recent_process_type{
    int reNum;
    int pagCnt;     // 请求进程页数
    int memCnt;     // 请求进程分配内存数
    vector<int> use_mem;
    // pagTab_type* pagTab;     // 页表项
    vector<pagTab_type> pagTab;         // 用vector存储便于直接索引
    // vector<int> use_opt;        // 用于opt算法的预处理未来队列,或请求表的转做队列,这个tui复杂了吧
    // wdnmd 不搞这个机制了
};
vector<recent_process_type*> recentProcess_vec;

const int INF = 0x3f3f3f3f;
int mem_size = DEFAULT_MEM_SIZE;  /*内存大小*/
int ma_algorithm = 1;           /*当前分配算法*/
// static int pid = 0;             /*初始pid*/
int flag = 0;                   /*设置内存大小标志*/
int sumMem;
int exMemPtr = 0;       // 外存使用记录
int linePtr = 0;        // 读入文件的行记录

void rearrange_fifo(int num, int pagPtr, recent_process_type* nowProcess, int CoR);
void rearrange_lru(int num, int pagPtr, recent_process_type* nowProcess, int CoR);
void rearrange_opt(int num, int pagPtr, recent_process_type* nowProcess, int CoR);
void rearrange_clock(int num, int pagPtr, recent_process_type* nowProcess, int CoR);
void rearrange_iClock(int num, int pagPtr, recent_process_type* nowProcess, int CoR);

///
//
//                  莫生气,莫生气
//                  辣鸡代码非我意
//                  气出病来谁如意
//                  谈笑风生活长命
//
///

/*显示菜单信息*/
void display_menu(){
	printf("\n");
	printf("1.display memory size(default = %d)\n", DEFAULT_MEM_SIZE);
	printf("2.Select memory allocation algorithm\n");
	printf("3.Read request from file\n");
	printf("4.Terminate a process\n");
	printf("5.Display memory usage\n");
	printf("0.exit\n");
}

void write_to_swap(int num, int pagPtr){
    FILE * pFile;
    pFile = fopen("D:/auxiliaryPlane/project/scuCode/lessson/swap_area.txt", "a");
    fprintf(pFile, "%d %d\n", num,pagPtr);
    fclose(pFile);
    return;
}

void set_algorithm(){
	int algorithm;
    printf("\t1.First Input First Output\n");
    printf("\t2.Leatest Recently Used\n");
	printf("\t3.Optimal\n");
    printf("\t4.Clock\n");
    printf("\t5.Improved Clock\n");
	scanf("%d", &algorithm);

	if (algorithm >= 1 && algorithm <= 5){
		ma_algorithm = algorithm;	
	}
	// rearrange(ma_algorithm);
}

void rearrange(int num, int pagPtr, recent_process_type* nowProcess, int CoR){
	switch(ma_algorithm){
		case 1:rearrange_fifo(num, pagPtr, nowProcess, CoR);
		break;
		case 2:rearrange_lru(num, pagPtr, nowProcess, CoR);
		break;
		case 3:rearrange_opt(num, pagPtr, nowProcess, CoR);
		break;
        case 4:rearrange_clock(num, pagPtr, nowProcess, CoR);
		break;
        case 5:rearrange_iClock(num, pagPtr, nowProcess, CoR);
		break;
	}
}

void rearrange_fifo(int num, int pagPtr, recent_process_type* nowProcess, int CoR){
	// 先看是否在内存
    if(nowProcess->pagTab[pagPtr].inMem == 1){
        int useMemNow = nowProcess->pagTab[pagPtr].memNum;
        if(memBlock[useMemNow].processNum != num || memBlock[useMemNow].stand == 0) {
            printf("wrong wrong\n");
        }
        memBlock[useMemNow].usedTime = linePtr;
        if(CoR == 0) nowProcess->pagTab[pagPtr].used = 1;
        else if(CoR == 1) nowProcess->pagTab[pagPtr].changed = 1;
        return ;    // 若该页表项仍在内存直接返回
    }
    // 不在内存,则应记录当前此进程使用的内存的最远、或者未用以及被其他进程占用的块
    int memToUse = -1, pTime = INF;
    for(int i=1;i<nowProcess->use_mem.size();i++){
        int useMemI = nowProcess->use_mem[i];
        if(memBlock[useMemI].stand == 0 || memBlock[useMemI].processNum != num){
            memBlock[useMemI].stand = 1;
            memBlock[useMemI].processNum = num;
            memBlock[useMemI].pageTime = linePtr;
            memBlock[useMemI].usedTime = linePtr;
            nowProcess->pagTab[pagPtr].inMem = 1;
            nowProcess->pagTab[pagPtr].memNum = useMemI;
            nowProcess->pagTab[pagPtr].used = nowProcess->pagTab[pagPtr].changed = 0;
            if(CoR == 0) nowProcess->pagTab[pagPtr].used = 1;
            else if(CoR == 1) nowProcess->pagTab[pagPtr].changed = 1;        
            break;
        } else if(memBlock[useMemI].pageTime < pTime){
            pTime = memBlock[useMemI].pageTime;
            memToUse = useMemI;
        }
    }
    if(nowProcess->pagTab[pagPtr].inMem == 0){
        if(nowProcess->pagTab[pagPtr].changed == 1) write_to_swap(num, pagPtr);
        memBlock[memToUse].stand = 1;
        memBlock[memToUse].processNum = num;
        memBlock[memToUse].pageTime = linePtr;
        memBlock[memToUse].usedTime = linePtr;
        nowProcess->pagTab[pagPtr].inMem = 1;
        nowProcess->pagTab[pagPtr].memNum = memToUse;
        // nowProcess->pagTab[pagPtr].used = 1; 
        nowProcess->pagTab[pagPtr].used = nowProcess->pagTab[pagPtr].changed = 0;
        if(CoR == 0) nowProcess->pagTab[pagPtr].used = 1;
        else if(CoR == 1) nowProcess->pagTab[pagPtr].changed = 1;           
    }
}

void rearrange_lru(int num, int pagPtr, recent_process_type* nowProcess, int CoR){
    // 先看是否在内存
    if(nowProcess->pagTab[pagPtr].inMem == 1){
        int useMemNow = nowProcess->pagTab[pagPtr].memNum;
        if(memBlock[useMemNow].processNum != num || memBlock[useMemNow].stand == 0) {
            printf("wrong wrong\n");
        }
        memBlock[useMemNow].usedTime = linePtr;
        if(CoR == 0) nowProcess->pagTab[pagPtr].used = 1;
        else if(CoR == 1) nowProcess->pagTab[pagPtr].changed = 1;
        return ;    // 若该页表项仍在内存直接返回
    }
    // 不在内存,则应记录当前此进程使用的内存的最近最久未用、或者未用以及被其他进程占用的块
    int memToUse = -1, pTime = INF;
    for(int i=1;i<nowProcess->use_mem.size();i++){
        int useMemI = nowProcess->use_mem[i];
        if(memBlock[useMemI].stand == 0 || memBlock[useMemI].processNum != num){
            memBlock[useMemI].stand = 1;
            memBlock[useMemI].processNum = num;
            memBlock[useMemI].pageTime = linePtr;
            memBlock[useMemI].usedTime = linePtr;
            nowProcess->pagTab[pagPtr].inMem = 1;
            nowProcess->pagTab[pagPtr].memNum = useMemI;
            // nowProcess->pagTab[pagPtr].used = 1; 
            nowProcess->pagTab[pagPtr].used = nowProcess->pagTab[pagPtr].changed = 0;
            if(CoR == 0) nowProcess->pagTab[pagPtr].used = 1;
            else if(CoR == 1) nowProcess->pagTab[pagPtr].changed = 1;           
            break;
        } else if(memBlock[useMemI].usedTime < pTime){
            pTime = memBlock[useMemI].usedTime;
            memToUse = useMemI;
        }
    }
    if(nowProcess->pagTab[pagPtr].inMem == 0){
        if(nowProcess->pagTab[pagPtr].changed == 1) write_to_swap(num, pagPtr);
        // memBlock[memToUse].stand = 1;        // 这个理论上不需要换
        memBlock[memToUse].processNum = num;
        memBlock[memToUse].pageTime = linePtr;
        memBlock[memToUse].usedTime = linePtr;
        nowProcess->pagTab[pagPtr].inMem = 1;
        nowProcess->pagTab[pagPtr].memNum = memToUse;
        // nowProcess->pagTab[pagPtr].used = 1; 
        nowProcess->pagTab[pagPtr].used = nowProcess->pagTab[pagPtr].changed = 0;
        if(CoR == 0) nowProcess->pagTab[pagPtr].used = 1;
        else if(CoR == 1) nowProcess->pagTab[pagPtr].changed = 1;      
    }
}

bool vis_page[max_memBlock];
void rearrange_opt(int num, int pagPtr, recent_process_type* nowProcess, int CoR){
    // 先看是否在内存
    if(nowProcess->pagTab[pagPtr].inMem == 1){
        int useMemNow = nowProcess->pagTab[pagPtr].memNum;
        if(memBlock[useMemNow].processNum != num || memBlock[useMemNow].stand == 0) {
            printf("wrong wrong\n");
        }
        memBlock[useMemNow].usedTime = linePtr;
        if(CoR == 0) nowProcess->pagTab[pagPtr].used = 1;
        else if(CoR == 1) nowProcess->pagTab[pagPtr].changed = 1;
        return ;    // 若该页表项仍在内存直接返回
    }
    // 不在内存,先找未用以及被其他进程占用的块
    for(int i=1;i<nowProcess->use_mem.size();i++){
        int useMemI = nowProcess->use_mem[i];
        if(memBlock[useMemI].stand == 0 || memBlock[useMemI].processNum != num){
            memBlock[useMemI].stand = 1;
            memBlock[useMemI].processNum = num;
            memBlock[useMemI].pageTime = linePtr;
            memBlock[useMemI].usedTime = linePtr;
            nowProcess->pagTab[pagPtr].inMem = 1;
            nowProcess->pagTab[pagPtr].memNum = useMemI;
            // nowProcess->pagTab[pagPtr].used = 1;  
            nowProcess->pagTab[pagPtr].used = nowProcess->pagTab[pagPtr].changed = 0;
            if(CoR == 0) nowProcess->pagTab[pagPtr].used = 1;
            else if(CoR == 1) nowProcess->pagTab[pagPtr].changed = 1;          
            return ;
        }
    }
    // 所有块都被当前的进程占用,则要找未来最远使用的块
    FILE *fp = NULL;
    fp = fopen("D:/auxiliaryPlane/project/scuCode/lessson/request_form.txt", "r");
    char* tempStr = new char[20];
    // int* tempA = new int[nowProcess->memCnt];
    memset(vis_page,0,sizeof(vis_page));
    for (int i=0;i<linePtr;i++) fscanf(fp,"%*[^\n]%*c");    // 跳过前linePtr行
    int findCnt = 0;        // 记录找到了几个页,方便剪枝

    while(fscanf(fp, "%s", tempStr)){
        int aa, bb, cc;
        if(strcmp("tempStr","read") || strcmp("tempStr","modify")){
            fscanf(fp, "%d %d",&aa,&bb);
            if(aa == num){
                if(nowProcess->pagTab[bb].inMem == 1 && vis_page[bb] == 0){
                    findCnt++;
                    vis_page[bb] = 1;
                }
                if(findCnt == nowProcess->memCnt-1) break;
            }
        } else { fscanf(fp, "%d %d %d",&aa,&bb,&cc); }
    }
    fclose(fp);

    int findAns = -1;
    for(int i=0;i<nowProcess->pagTab.size();i++){
        if(nowProcess->pagTab[i].inMem == 1 && vis_page[i] == 0){
            findAns = i; break;
        }
    }
    // 此时所引导将替换页号,取出对应内存块号
    if(nowProcess->pagTab[pagPtr].changed == 1) write_to_swap(num, pagPtr);
    int memToUse = nowProcess->pagTab[findAns].memNum;
    memBlock[memToUse].processNum = num;
    memBlock[memToUse].pageTime = linePtr;
    memBlock[memToUse].usedTime = linePtr;
    nowProcess->pagTab[pagPtr].inMem = 1;
    nowProcess->pagTab[pagPtr].memNum = memToUse;
    // nowProcess->pagTab[pagPtr].used = 1;
    nowProcess->pagTab[pagPtr].used = nowProcess->pagTab[pagPtr].changed = 0;
    if(CoR == 0) nowProcess->pagTab[pagPtr].used = 1;
    else if(CoR == 1) nowProcess->pagTab[pagPtr].changed = 1;
    delete tempStr;
}

void rearrange_clock(int num, int pagPtr, recent_process_type* nowProcess, int CoR){
    // 先看是否在内存
    if(nowProcess->pagTab[pagPtr].inMem == 1){
        int useMemNow = nowProcess->pagTab[pagPtr].memNum;
        if(memBlock[useMemNow].processNum != num || memBlock[useMemNow].stand == 0) {
            printf("wrong wrong\n");
        }
        memBlock[useMemNow].usedTime = linePtr;
        if(CoR == 0) nowProcess->pagTab[pagPtr].used = 1;
        else if(CoR == 1) nowProcess->pagTab[pagPtr].changed = 1;
        return ;    // 若该页表项仍在内存直接返回
    }
    // 不在内存,先找未用以及被其他进程占用的块
    for(int i=1;i<nowProcess->use_mem.size();i++){
        int useMemI = nowProcess->use_mem[i];
        if(memBlock[useMemI].stand == 0 || memBlock[useMemI].processNum != num){
            memBlock[useMemI].stand = 1;
            memBlock[useMemI].processNum = num;
            memBlock[useMemI].pageTime = linePtr;
            memBlock[useMemI].usedTime = linePtr;
            nowProcess->pagTab[pagPtr].inMem = 1;
            nowProcess->pagTab[pagPtr].memNum = useMemI;
            // nowProcess->pagTab[pagPtr].used = 1;  
            nowProcess->pagTab[pagPtr].used = nowProcess->pagTab[pagPtr].changed = 0;
            if(CoR == 0) nowProcess->pagTab[pagPtr].used = 1;
            else if(CoR == 1) nowProcess->pagTab[pagPtr].changed = 1;          
            return ;
        }
    }
    // 内存都被占用则需进行置换
    while(1){
        for(int i=0;i<nowProcess->pagTab.size();i++){
            if(nowProcess->pagTab[i].inMem == 1){
                if(nowProcess->pagTab[i].used == 0){
                    if(nowProcess->pagTab[pagPtr].changed == 1) write_to_swap(num, pagPtr);
                    int memToUse = nowProcess->pagTab[i].memNum;
                    memBlock[memToUse].processNum = num;
                    memBlock[memToUse].pageTime = linePtr;
                    memBlock[memToUse].usedTime = linePtr;
                    nowProcess->pagTab[pagPtr].inMem = 1;
                    nowProcess->pagTab[pagPtr].memNum = memToUse;
                    nowProcess->pagTab[pagPtr].used = nowProcess->pagTab[pagPtr].changed = 0;
                    if(CoR == 0) nowProcess->pagTab[pagPtr].used = 1;
                    else if(CoR == 1) nowProcess->pagTab[pagPtr].changed = 1;
                    return ;
                } else if(nowProcess->pagTab[i].used == 1){
                    nowProcess->pagTab[i].used = 0;
                }
            }
        }
    }
}

void rearrange_iClock(int num, int pagPtr, recent_process_type* nowProcess, int CoR){
    /*  此时要明确一个前提,如果是其他算法,也需要同时记录是change还是read */
    /* 将一个页面换出时,若该页已经被修改,则需要将他重新写回磁盘上 */
    /* 那么意思就是这个时候写进交换区????? */
    // 先看是否在内存
    if(nowProcess->pagTab[pagPtr].inMem == 1){
        int useMemNow = nowProcess->pagTab[pagPtr].memNum;
        if(memBlock[useMemNow].processNum != num || memBlock[useMemNow].stand == 0) {
            printf("wrong wrong\n");
        }
        memBlock[useMemNow].usedTime = linePtr;
        if(CoR == 0) nowProcess->pagTab[pagPtr].used = 1;
        else if(CoR == 1) nowProcess->pagTab[pagPtr].changed = 1;
        return ;    // 若该页表项仍在内存直接返回
    }
    // 不在内存,先找未用以及被其他进程占用的块
    for(int i=1;i<nowProcess->use_mem.size();i++){
        int useMemI = nowProcess->use_mem[i];
        if(memBlock[useMemI].stand == 0 || memBlock[useMemI].processNum != num){
            // if(nowProcess->pagTab[pagPtr].changed == 1) write_to_swap(num, pagPtr);
            memBlock[useMemI].stand = 1;
            memBlock[useMemI].processNum = num;
            memBlock[useMemI].pageTime = linePtr;
            memBlock[useMemI].usedTime = linePtr;
            nowProcess->pagTab[pagPtr].inMem = 1;
            nowProcess->pagTab[pagPtr].memNum = useMemI;
            // nowProcess->pagTab[pagPtr].used = 1;  
            nowProcess->pagTab[pagPtr].used = nowProcess->pagTab[pagPtr].changed = 0;
            if(CoR == 0) nowProcess->pagTab[pagPtr].used = 1;
            else if(CoR == 1) nowProcess->pagTab[pagPtr].changed = 1;          
            return ;
        }
    }
    // 内存都被占用则需进行置换
    while(1){
        // 1) 找最佳淘汰页,既没有被访问、也未被修改
        for(int i=0;i<nowProcess->pagTab.size();i++){
            if(nowProcess->pagTab[i].inMem == 1){
                if(nowProcess->pagTab[i].used == 0 && nowProcess->pagTab[i].changed == 0){
                    if(nowProcess->pagTab[pagPtr].changed == 1) write_to_swap(num, pagPtr);
                    int memToUse = nowProcess->pagTab[i].memNum;
                    memBlock[memToUse].processNum = num;
                    memBlock[memToUse].pageTime = linePtr;
                    memBlock[memToUse].usedTime = linePtr;
                    nowProcess->pagTab[pagPtr].inMem = 1;
                    nowProcess->pagTab[pagPtr].memNum = memToUse;
                    nowProcess->pagTab[pagPtr].used = nowProcess->pagTab[pagPtr].changed = 0;
                    if(CoR == 0) nowProcess->pagTab[pagPtr].used = 1;
                    else if(CoR == 1) nowProcess->pagTab[pagPtr].changed = 1;
                    return ;
                }
            }
        }
        // 2) 查找第二类页面,未被访问,已被修改,且将扫描过的访问位置0
        for(int i=0;i<nowProcess->pagTab.size();i++){
            if(nowProcess->pagTab[i].inMem == 1){
                if(nowProcess->pagTab[i].used == 0 && nowProcess->pagTab[i].used == 1){
                    if(nowProcess->pagTab[pagPtr].changed == 1) write_to_swap(num, pagPtr);
                    int memToUse = nowProcess->pagTab[i].memNum;
                    memBlock[memToUse].processNum = num;
                    memBlock[memToUse].pageTime = linePtr;
                    memBlock[memToUse].usedTime = linePtr;
                    nowProcess->pagTab[pagPtr].inMem = 1;
                    nowProcess->pagTab[pagPtr].memNum = memToUse;
                    nowProcess->pagTab[pagPtr].used = nowProcess->pagTab[pagPtr].changed = 0;
                    if(CoR == 0) nowProcess->pagTab[pagPtr].used = 1;
                    else if(CoR == 1) nowProcess->pagTab[pagPtr].changed = 1;
                    return ;
                } else if(nowProcess->pagTab[i].used == 1){
                    nowProcess->pagTab[i].used = 0;
                }
            }
        }
        // 3) 从第一步重复再到第二步重复,一定能找到
    }
}

int display_mem_size(){
    printf("default : 10MB\n");
}

/*初始化空闲块,默认一块,可以指定大小及初始地址*/
int init_memBolck(){
    // 内存块和空闲页表链功能重复啊,先不管空闲页表链了
    for(int i=0;i<max_memBlock;i++){
        memBlock->stand = 0;    // 此时未被占用,置为0
    }
    // 对换区清空
    FILE *fp;
    fp=fopen("D:/auxiliaryPlane/project/scuCode/lessson/swap_area.txt","w");
    fclose(fp);             //这样就清空了内容
    // 请求链表清空
    return 0;
}

int init_pagTable(){
    return 0;
}

/*创建新的进程,输入新的进程编号、进程总页数、进程分配内存块数*/
int new_process(int num, int pagCnt, int memCnt){
    // struct pagTab_type *process = new pagTab_type[1024];
    int tempCnt = 0;
    for(int i=0;i<max_memBlock;i++){
        if(memBlock[i].stand == 0){
            tempCnt++;
        }
        if(tempCnt >= memCnt) break;
    }
    if(tempCnt >= memCnt){
        // 内存容量足够、分配内存
        struct recent_process_type* tempProcess= new recent_process_type;
        tempProcess->reNum = num;
        tempProcess->pagCnt = pagCnt;
        tempProcess->memCnt = memCnt;
        for(int i=0;i<max_memBlock;i++){
            if(memBlock[i].stand == 0){
                memBlock[i].stand = 1;
                tempProcess->use_mem.push_back(i);
            }
        }
        for(int i=0;i<pagCnt;i++){
            struct pagTab_type* tempPagTab = new pagTab_type;
            tempPagTab->logNum = i;
            tempPagTab->exStorNum = exMemPtr++;     // 存入外存使用块
            tempProcess->pagTab.push_back(*tempPagTab);
        }
        // recentProcess_vec.push_back(tempProcess);
        // 此时要为了opt算法进行文件后续指令队列的预处理
        // 拉倒吧,不整这个了,这个破玩意还是玩临时的吧
        recentProcess_vec.push_back(tempProcess);
    } else {
        // 加入请求表队列中等待
        request_type *tempProcess = new request_type;
        tempProcess->reNum = num;
        tempProcess->pagCnt = pagCnt;
        tempProcess->memCnt = memCnt;
        request_vec.push_back(tempProcess);
    }
}

int read_process(int num, int pagPtr, int CoR){
    // 如果在当前队列中
    for(int i=0;i<recentProcess_vec.size();i++){
        if(recentProcess_vec[i]->reNum == num){
            rearrange(num, pagPtr, recentProcess_vec[i], CoR);
            return 1;
        }
    }
    // 如果在请求队列中
    for(int i=0;i<request_vec.size();i++){
        if(request_vec[i]->reNum == num){
            request_vec[i]->readIn.push_back(pagPtr);
            return 2;
        }
    }
    return 0;
}

int read_request(){
    printf("the num of line to read : ");
    int lineNum;
    scanf("%d",&lineNum);
    FILE *fp = NULL;
    fp = fopen("D:/auxiliaryPlane/project/scuCode/lessson/request_form.txt", "r");
    char* strIn = new char[100];
    while (lineNum--){
        fscanf(fp, "%s", strIn);
        if(strcmp(strIn,"create")){
            int num, pagCnt, memCnt;
            fscanf(fp, "%d %d %d",&num,&pagCnt,&memCnt);
            new_process(num, pagCnt, memCnt);
        } else if(strcmp(strIn, "read")){
            int num, pagPtr;
            fscanf(fp, "%d %d", &num, &pagPtr);
            read_process(num, pagPtr, 0);
        } else if(strcmp(strIn, "modify")){
            int num, pagPtr;
            fscanf(fp, "%d %d", &num, &pagPtr);
            read_process(num, pagPtr, 1);
        }
        linePtr++;      // 读入文件总行数,用以记录内存置换时间
	}
    fclose(fp);
}

/*删除进程,归还分配的存储空间,并删除描述该进程内存分配的节点*/
void kill_process(){
    printf("the num of process you want to kill : ");
    int num;
    scanf("%d",&num);
    for(int i=0;i<recentProcess_vec.size();i++){
        if(recentProcess_vec[i]->reNum == num){
            // 内存块置位
            for(int j=0;j<recentProcess_vec[i]->use_mem.size();j++){
                memBlock[recentProcess_vec[i]->use_mem[j] ].stand = 0;
                // .....
            }
            // 页表清空
            recentProcess_vec[i]->pagTab.clear();
        }
        // 进程表清空
        recentProcess_vec[i]->reNum = -1;
        // .....
    }
}

/*显示当前的内存使用情况,包括空闲区的情况和已经分配的情况*/
int display_mem_usage(){
	// 空闲区数, 空闲区总数,空闲区容量,已分配内存和分配归属
    printf("--------------------------------------------------\n");
    printf("\tfree_block\t\tsize(KB)\n");
    for(int i=0;i<max_memBlock;i++){
        if(memBlock[i].stand == 0){
            int startMem = i;
            int cntMem = 1;
            i++;
            while(memBlock[i].stand == 0){
                i++;
                cntMem++;
            }
            printf("\t%d\t\t%d\n",startMem,cntMem*4);
        }
    }
    printf("\tused block\t\tsize(KB)\t\tbelong to\n");
    for(int i=0;i<max_memBlock;i++){
        if(memBlock[i].stand == 1){
            printf("\t%d\t\t4KB\t\t%d\n",i,memBlock[i].processNum);
        }
    }
    printf("--------------------------------------------------\n");
}


int main()
{
    init_memBolck();
    init_pagTable();
    int choice;
    // freopen("D:/auxiliaryPlane/project/scuCode/lesson/request_form.txt","r",stdin);
    while (1){
		display_menu();  //显示菜单
		printf("\tyour choose :");
		scanf("%d", &choice);
		switch(choice){
			case 1:display_mem_size();   //设置内存大小
			break;
			case 2:set_algorithm();
				 flag = 1;         //设置算法
			break;
			case 3:read_request();
				 flag = 1;      //读取进程以及访问页面输入
			break;
			case 4:kill_process();
				 flag = 1;      //删除进程
			break;
			case 5:display_mem_usage();
				 flag = 1;	//显示内存使用
			break;
			case 0://do_exit();
				 exit(0);          //释放链表并退出
			default: break;
		}
	}
    return 0;
}
实验目的】 1. 通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解; 2. 熟悉虚存管理的各种页面淘汰算法; 3. 通过编写和调试地址转换过程的模拟程序以加强对地址转换过程的了解。 【实验准备】 1.虚拟存储器的管理方式  段式管理  页式管理  段页式管理 2.页面置换算法  先进先出置换算法  最近最久未使用置换算法  Clock置换算法  其他置换算法 【实验内容】 1. 实验题目 设计一个请求页式存储管理方案。并编写模拟程序实现之。产生一个需要访问的指令地址流。它是一系列需要访问的指令的地址。为不失一般性,你可以适当地(用人工指定地方法或用随机数产生器)生成这个序列,使得 50%的指令是顺序执行的。25%的指令均匀地散布在前地址部分,25%的地址是均匀地散布在后地址部分。为简单起见。页面淘汰算法采用 FIFO页面淘汰算法,并且在淘汰一页时,只将该页在页表中抹去。而不再判断它是否被改写过,也不将它写回到辅存。 2. 具体做法 产生一个需要访问的指令地址流;指令合适的页面尺寸(例如以 1K或2K为1页);指定内存页表的最大长度,并对页表进行初始化;每访问一个地址时,首先要计算该地址所在的页的页号,然后查页表,判断该页是否在主存——如果该页已在主存,则打印页表情况;如果该页不在主存且页表未满,则调入一页并打印页表情况;如果该页不足主存且页表已满,则按 FIFO页面淘汰算法淘汰一页后调入所需的页,打印页表情况;逐个地址访问,直到所有地址访问完毕。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值