实验六 存储管理

该博客围绕存储管理实验展开,要求编写程序利用内存映象文件实现less工具多屏显示功能。介绍了less工具在Linux下查看文件内容的特点,阐述代码实现思路,包括打开文件、获取文件大小、映射内存、分屏显示及相关指令操作,最后解除映射并关闭文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实验六 :存储管理

编写一个程序,利用内存映象文件,实现less工具的功能(多屏显示)。

  • 首先对less工具做一下介绍:less命令在linux下可以用于查看文件的内容,使用了 less 时,就可以使用 ↑ ↓ 等按 键的功能来往前往后翻看文件,更容易查看一个文件的内容、除此之外,在 less 里头可以拥有更多的搜索功能,不止可以向下搜,也可以向上搜

本题要求利用镜像文件简单实现less工具的功能,并且能够多屏显示内容。所以在下属代码书写中,使用了一次最多可以输出7行的显示方法,当继续使用空格时,可以继续显示下面7行的内容,除此之外,可以使用d命令实现查看以当前行为参照的下一行的内容,u命令用于显示以当前行为参照的上一行的内容,q表示退出指令。

代码如下:

#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <memory.h>
#include <stdlib.h>
#include <stdio.h>
int lastrow(char *s, int d);
int nextrow(char *s, int d);
int onepage(char *s, int d);
int main()
{
    int fd, play = 0;
    char lab;
    char *start;
    struct stat sb;
    fd = open("王伟家.txt", O_RDONLY); //以只读方式打开文件
    fstat(fd, &sb);               //用来获取文件的大小
    /*
    *NULL表示让系统自动选定地址,
    *sb.st_size表示上一句的文件大小,对应到内存中的大小
    *PROT_READ表示映射区域可被读取
    *MAP_PRIVATE 对映射区域的写入操作会产生一个映射文件的复制,
    *即私人的“写入时复制”(copy on write)对此区域作的任何修改都不会写回原来的文件内容。
    *fd代表映射到内存的文件
    *0代表文件映射的偏移量
    *返回值为映射区的内存的起始地址
    */
    start = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
    if (start == MAP_FAILED) //MAP_FAILED表示映射不成功 直接返回
        return (1);
    play = onepage(start, play) + 1;
    lab = getchar();
    while (lab != 'q' && lab != 'Q')     //输入的字符为Q或者q 那么就会退出
    {
        if (play > sb.st_size)          //如果onepage返回的字节数大于文件的大小 则任意输入一个数退出
        {
            lab = getchar();
            break;
        }
        else if (lab == ' ')           //如果输入的是空格字符 则从上次结束的地方继续向屏幕读处下面10行的内容
            play = play + 1 + onepage(start, play);
        else if (lab == 'D' || lab == 'd')  //如果输入的是D或d则读出下一行
            play = play + 1 + nextrow(start, play);
        else if (lab == 'U' || lab == 'u')
            play = 1 + lastrow(start, play);
        lab = getchar();
    }
    munmap(start, sb.st_size);  //解除映射
    close(fd);                  //关闭文件
    return 0;
}
int onepage(char *s, int d)
{
    int i, count = 0;            //count在这里表示文件中行的数量
    char *buffer = malloc(2048); //配置内存空间,由buffer指向该空间

    s += d;              /*每7行作为一页输出*/
    for (i = 0; i < 2048; i++)
    {
        if (s[i] == '\n')
            count++;
        if (count == 7)
            break;            //当达到7行之后 跳出循环
    }
    memcpy(buffer, s, i);    //从s处开始的地方拷贝i个字节到buffer区域
    buffer[i] = '\0';        //给buffer添加结束符
    printf("%s\n", buffer);
    return i;
}
int nextrow(char *s, int d)   //输出以当前为参照的下一行的内容
{
    int i;
    char *buffer = malloc(100);
    s += d;
    for (i = 0; i < 100; i++)
        if (s[i] == '\n')
            break;
    memcpy(buffer, s, i);
    buffer[i] = '\0';
    printf("%s\n", buffer);
    return i;
}
int lastrow(char *s, int d)   //输出以当前为参照的上一行的内容
{
    int i, count = 0;
    char *buffer = malloc(100);
    int py = d;
    for (; d > 0; d--)
    {
        if (s[d] == '\n')
            count++;
        if (count == 2)
            break;
    }
    memcpy(buffer, s + d + 1, py - d - 2);
    buffer[py - d - 2] = '\0';
    printf("%s\n", buffer);
    return d;
}

打开的文件以及执行示意图如下:
在这里插入图片描述在这里插入图片描述

对上述代码所做的解释:

在上述代码中,首先以只读的方式打开一个文件,使用fstat()函数获取到该文件的大小,以防止在后续读取文件内容时越界。使用mmap()函数将文件的内容映射到内存中,加快读写的速率,并返回该文件的内容在内存中的起始地址。使用onepage函数一次性显示7行的内容,并返回该7行中左右的字节数,接下来输入字符,用于来决定进行何种操作,如果输入q指令,则退出读取文件的操作,如果使用空格指令,则继续读取下面的7行内容,实现分屏显示的功能。使用d指令,表示读取以当前行为参照的下一行的内容,使用u命令表示读取以当前行为参照的上一行的内容。最后读取文件内容完毕之后,解除映射,并关闭文件。

实验目的】 1. 通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解; 2. 熟悉虚存管理的各种页面淘汰算法; 3. 通过编写和调试地址转换过程的模拟程序以加强对地址转换过程的了解。 【实验准备】 1.虚拟存储器的管理方式  段式管理  页式管理  段页式管理 2.页面置换算法  先进先出置换算法  最近最久未使用置换算法  Clock置换算法  其他置换算法 【实验内容】 1. 实验题目 设计一个请求页式存储管理方案。并编写模拟程序实现之。产生一个需要访问的指令地址流。它是一系列需要访问的指令的地址。为不失一般性,你可以适当地(用人工指定地方法或用随机数产生器)生成这个序列,使得 50%的指令是顺序执行的。25%的指令均匀地散布在前地址部分,25%的地址是均匀地散布在后地址部分。为简单起见。页面淘汰算法采用 FIFO页面淘汰算法,并且在淘汰一页时,只将该页在页表中抹去。而不再判断它是否被改写过,也不将它写回到辅存。 2. 具体做法 产生一个需要访问的指令地址流;指令合适的页面尺寸(例如以 1K或2K为1页);指定内存页表的最大长度,并对页表进行初始化;每访问一个地址时,首先要计算该地址所在的页的页号,然后查页表,判断该页是否在主存——如果该页已在主存,则打印页表情况;如果该页不在主存且页表未满,则调入一页并打印页表情况;如果该页不足主存且页表已满,则按 FIFO页面淘汰算法淘汰一页后调入所需的页,打印页表情况;逐个地址访问,直到所有地址访问完毕。
一. 实验目的: 1.通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解。熟悉虚存管理的各种页面淘汰算法 2.通过编写和调试地址转换过程的模拟程序以加强对地址转换过程的了解。 二.实验要求 实验程序由以下三大部分组成: (1) 通过随机数产生一个指令序列(实际上是指令的逻辑地址序列),共320条指令。指令的地址按下述原则生成: A:50%的指令是顺序执行的 B:25%的指令要实现向前跳转,均匀分布在前地址部分 C:25%的指令要实现向后跳转,均匀分布在后地址部分 具体的实施方法是: A:在[0,319]的指令地址之间随机选取一起点m B:顺序执行一条指令,即执行地址为m+1的指令 C:在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m’ D:顺序执行一条指令,其地址为m’+1 E:在后地址[m’+2,319]中随机选取一条指令并执行 F:重复步骤A-E,直到320次指令 (2) 将每条指令的逻辑地址变换为页地址 设:页面大小为1K; 用户内存容量4页到32页; 用户虚存容量为32K。 在用户虚存中,按每K存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为: 第 0 条-第 9 条指令为第0页(对应逻辑地址为[0,9]) 第10条-第19条指令为第1页(对应逻辑地址为[10,19]) ……………………………… 第310条-第319条指令为第31页(对应逻辑地址为[310,319]) 按以上方式,用户指令可组成32页。 (3) 分别使用FIFO算法和LFU算法,计算给用户进程的这32页分配4,5,…,32个页面(内存)时其缺页率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值