【HIT-计算机系统】ICS-Lab8 Dynamic Storage Allocator

2023-11-11

第1章 实验基本信息

1.1 实验目的

理解现代计算机系统虚拟存储的基本知识;

掌握C语言指针相关的基本操作;

深入理解动态存储申请、释放的基本原理和相关系统函数;

用C语言实现动态存储分配器,并进行测试分析;

培养Linux下的软件系统开发与测试能力。

1.2 实验环境与工具

1.2.1 硬件环境

x64 CPU;1.60GHz;8G RAM;256GHD Disk。

1.2.2 软件环境

Windows10 64位。

1.2.3 开发工具

VM VirtualBox 6.1;Ubuntu 20.04 LTS 64位;

Visual Studio 2019 64位;CodeBlocks 17.12 64位;vi/vim/gedit+gcc;

cpu-z;Gprof;Valgrind。

1.3 实验预习

见第二章

第2章 实验预习

总分20

2.1 动态内存分配器的基本原理(5分)

动态内存分配器维护着一个进程的虚拟内存区域,称为堆(heap)。系统之间细节不同,但是不失通用性,假设堆是一个请求二进制零的区域,它紧接在未初始化的数据区域后开始,并向上生长(向更高的地址)。对于每个进程,内核维护着一个变量brk(读做“break”),它指向堆的顶部。

分配器将堆视为一组不同大小的块(clock)的集合来维护。每个块就是一个连续的虚拟内存片(chunk),要么是已分配的,要么是空闲的。已分配的块显式地保留为供应用程序使用。空闲块可用来分配。空闲块保持空闲,直到它显式地被应用所分配。一个己分配的块保持已分配状态,直到它被释放,这种释放要么是应用程序显式执行的,要么是内存分配器自身隐式执行的。

2.2 带边界标签的隐式空闲链表分配器原理(5分)

隐式空闲链表简单形式(带边界标签在下面)

这种情况下,一个块是由一个字的头部、有效载荷,以及可能的填充组成。头部编码了这个块的大小(包括头部和所有的填充),以及这个块是已分配的还是空闲的。

头部后面是应用malloc时请求的有效载荷。有效载荷后面是一片不使用的填充块,其大小可以是任意的。

块的格式如图所示,我们可以将堆组织为一个连续的已分配块和空闲块的序列。

我们称这种结构为隐式空闲链表,是因为空闲块是通过头部中的大小字段隐含地连接着的。

2.2.1放置已分配的块

当一个应用请求一个k字节的块时,分配器搜索空闲链表,查找一个足够大可以放置所请求的空闲块。分配器执行这种搜索方式是由放置策略确定的,一些常见策略是首次适配、下一次适配和最佳适配。

2.2.2分割空闲块

一旦分配器找到一个匹配的空闲块,就必须做一个另策决定,那就是分配这个块多少空间。

分配器通常会选择将这个空闲块分割为两部分。第一部分变为了已分配块,而剩下的变成一个新的空闲块。

2.2.3获取额外的堆内存

如果分配器不能为请求块找到空闲块,一个选择是合并那些在物理内存上相邻的空闲块来创建一个更大的空闲块。然而如果这样还是不能生成一个足够大的块,或者空闲块已经最大程度地合并了,分配器会通过调用sbrk函数,向内核请求额外的内存。分配器将额外的内存转化成一个大的空闲块,将这个块插入到空闲链表中,然后将被请求的块放置在这个新的空闲块中。

2.2.4合并空闲块

Knuth提出了一种聪明而通用的技术,叫做边界标记(boundary tag),在每个块的结尾处添加一个脚部(footer,边界标记),其中脚部就是头部的一个副本。如果每个块包括这样一个脚部,那么分配器就可以通过检查它的脚部,判断前面一个块的起始位置和状态,这个脚部总是在距当前块开始位置一个字的距离。

2.3 显式空间链表的基本原理(5分)

一种更好的方法是将空闲块组织为某种形式的显式数据结构。因为根据定义, 程序不需要一个空闲块的主体,所以实现这个数据结构的指针可以存放在这些空闲块的主体里面。例如,堆可以组织成一个双向空闲链表,在每个空闲块中,都包含一个pred(前驱)和succ(后继)指针。

2.4 红黑树的结构、查找、更新算法(5分)

2.4.1结构

红黑树是一种近似平衡的二叉查找树,它能够确保任何一个节点的左右子树的高度差不会超过二者中较低那个的一倍。具体来说,红黑树是满足如下条件的二叉查找树(binary search tree):

  1. 每个节点要么是红色,要么是黑色。
  2. 根节点必须是黑色。
  3. 红色节点不能连续(也即是,红色节点的孩子和父亲都不能是红色)。
  4. 对于每个节点,从该点至null(树尾端)的任何路径,都含有相同个数的黑色节点。

在树的结构发生改变时(插入或者删除操作),往往会破坏上述条件3或条件4,需要通过调整使得查找树重新满足红黑树的条件。

红黑树的条件被破坏时,需要通过调整使得查找树重新满足红黑树的条件。调整可以分为两类:一类是颜色调整,即改变某个节点的颜色;另一类是结构调整,集改变检索树的结构关系。结构调整过程包含两个基本操作:左旋(Rotate Left),右旋(RotateRight)。

(1)左旋

左旋的过程是将x的右子树绕x逆时针旋转,使得x的右子树成为x的父亲,同时修改相关节点的引用。旋转之后,二叉查找树的属性仍然满足。

(2)右旋

右旋的过程是将x的左子树绕x顺时针旋转,使得x的左子树成为x的父亲,同时修改相关节点的引用。旋转之后,二叉查找树的属性仍然满足。

2.4.2查找算法

类似二分查找,在通过左右旋维护好红黑树的基本结构后,红黑树为相对平衡的二叉查找树,通过二分查找可以使复杂度最坏为O(logn)。

2.4.3更新算法

在我们分离链表中应用则更新为删除和插入:都以查找算法为基础,删除或插入后通过左右旋转保持红黑树平衡。

第3章 分配器的设计与实现

总分50

3.1 总体设计(10分)

总体上使用显示双向空闲链表、基于边界标签的空闲块合并、首次适配放置策略的分配器。

3.1.1 堆结构

堆结构类似书上给的隐式空闲链表堆结构,我将原结构中填充字(padding)改为指向显示空闲链表的第一个空闲块的指针(root)。其余不变。

3.1.2 内存块结构

内存块包括空闲块和已分配块,按照书上给的带边界标记的双向空闲链表结构。已分配块的开始和结尾处有头部和脚部;空闲块除了头部和脚部外,在有效载荷的前一个字和第二个字存放祖先和后继指针,分别指向空闲链表中的前驱和后继空闲块。由于实验在32位环境下进行,指针和地址为4字节,虽然空闲块内比已分配块多出两个必须使用的8字节,但块大小仍然至少为16字节。

3.1.3首次适配

由于使用显示双向空闲链表,我们可以使用指针操作遍历整个空闲链表进行寻找合适的空闲块,选择第一个适配的空闲块。

3.1.4辅助操作函数

(1)bcheckout:将指定空闲块脱离空闲链表。脱离后要保持原链表中脱离块的前后关系,同时要考虑到脱离后链表为空的情况,共需要考虑四种情况,即对链表中前后邻接空闲块是否存在的四种情况分别进行处理。

(2)fbcheckin:将指定空闲块插入到空闲链表头部。插入时需要考虑链表是否为空。

(3)extend_heap:扩展堆,向内核请求额外的指定大小内存,其中大小需要进行对齐然后调用mem_sbrk进行申请。分配器将额外的内存转化成一个大的空闲块,将这个块插入到空闲链表中。

(4)place:使用指定空闲块分配指定大小的空闲块,若剩余大小不足块最小大小16字节,则改空闲块全部分配,将该块调用fbcheckout脱离空闲链表;若剩余大小大于16字节,则进行分割,需要分四种情况调整空闲块剩余部分与原块在空闲链表中的临近块之间的前后关系。

(5)find_fit:首次适配寻找合适大小的空闲块,若找到,则返回空闲块地址;若没找到(链表为空或链表中空闲块大小都不够),则返回NULL。

(6)printblock:打印块包含的信息,若不是结尾快,则打印块地址、头部和脚部的扩大小、是否为空闲块的标记位;若是结尾快,则只打印块地址。

(7)checkblock:检查块是否字节对齐,并检查块的头部和脚部包含的信息是否匹配。

3.2 关键函数设计(40分)

3.2.1 int mm_init(void)函数(5分)

函数功能:初始化堆。

处理流程:从内存系统得到四个字,每个字分别按照3.1.1中的堆结构安排为 指向空闲链表第一个块指针root,两个序言快,和一个结尾快。其 中由于初始 时空闲链表为空,root被设置指向NULL;两个空闲 块被设置为 大小为8的已分配块的头部和脚部;结尾快为大小为0 的已分配块,只有一个头部。结构初始化完毕后拓展初始堆。拓 展失败返回-1,拓展成功返回0。

要点分析:由于实验要求不能定义全局或静态的复合型数据类型,于是任何形 式的显示空闲链表都要在堆中进行定义,而不能设置全局变量。 在堆中定义时,要保证8字对齐,并且由于实验在32位环境下进 行,指针和地址为4字节,即一个字。

3.2.2 void mm_free(void *ptr)函数(5分)

函数功能:释放一个已分配块,并在释放后与邻接的空闲块进行合并。

参    数:需要释放的已分配块的有效载荷首地址。

处理流程:首先将这个已分配块的头部和脚部的分配标记设为0,这个已分配 块变为伪空闲块(祖先和后继指针没有设置,需要在合并后一并 设置),然后调用函数coalesce与邻接的空闲块进行合并。

要点分析:函数重点在coalesce函数,函数内前将已分配块的头部和脚部内的 标记设置为0,是为了与扩展堆之后进行空闲块合并的情况统一。

3.2.3 void *mm_realloc(void *ptr, size_t size)函数(5 分)

函数功能:对已分配块进行重新分配大小。

参    数:需要重新分配大小的已分配块的有效载荷首地址ptr与更改后的块 大小size字节。

处理流程:重新申请一个size字节大小的块,并将原数据复制过去,释放原来 的块的内存。若申请失败,则退出程序;若申请成功则返回重新 申请的块地址。

要点分析:不要更改原已分配块中有效载荷中的内容。

3.2.4 int mm_check(void)函数(5分)

函数功能:检查堆的一致性,若出现错误则打印提示信息。

处理流程:首先检查序言块是否按照标准设置,然后遍历所有块,查看每个块 是否8字节对齐、头部脚部对应,最后检查结尾快是否按照标准 设置。

要点分析:需要遍历所有块,而不只是空闲块。

3.2.5 void *mm_malloc(size_t size)函数(10分)

函数功能:申请一个size字节大小的块。

参    数:要申请的块大小size。

处理流程:首先调用find_fit在空闲链表中通过首次适配寻找大小足够的空闲 块,然后调用函数place,分割出多余部分;若没有找到大小合适 的空闲块,则直接扩展堆,然后分割扩展堆新分配的空闲块。返 回分配的块的地址。

要点分析:要通过申请的字节数根据对齐调整请求块大小,为头部和脚部留有 空间并满足双字对齐的要求。对于小于8字节的请求,最小的块 大小为16字节(包括头部和脚部);对于大于8字节的请求,应 向上舍入到最近的8的整数倍并加上头部和脚部的8字节。

3.2.6 static void *coalesce(void *bp)函数(10分)

函数功能:将待合并的空闲块与其邻接的空闲块合并。

参    数:待合并的空闲块有效载荷首地址。

处理流程:有四种情况分别进行处理:(1)当待合并块上下两个临界块均为 已分配块时,直接将空闲块插入空闲链表头(2)当待合并块上一 邻接块为已分配块、下一邻接块为空闲块时,将下一空闲块从空 闲链表脱离,与待合并块合并,再将新的空闲块插入到空闲链表 头(3)当待合并块上一邻接块为空闲块、下一邻接块为已分配块 时,将上一空闲块从空闲链表脱离,然后将地址转向上一块地址, 与待合并块合并,再将新的空闲块插入空闲链表头(4)当待合并 块上下邻接块都为空闲块时,将前后都脱离空闲链表,然后将地 址转向上一块地址,将两个空闲块与待合并块合并,再将新生成 的空闲块插入到空闲链表头。

要点分析:要分四种情况分别处理;由于合并时邻接的空闲块在空闲 链表 中,需要先调用fbcheckout函数将其脱离空闲链表,这时 fbcheckout函数内需要考虑空闲链表为空的情况;合并时,需要更 改头部和脚部,这时需要转移到合适的地址进行操作,即转移到 待合并的几个块中最前面的块的有效载荷的首地址,将头部和脚 部分别改为 几个待合并块的大小之和;合并后,调用fbcheckin函 数将合并生成的新空闲块插入到空闲链表头,这时也需要考虑空 闲链表为空的情况。

第4章测试

总分10

4.1 测试方法

(1)在命令行输入make生成可执行评测程序文件;

(2)使用命令./mdriver -v -t traces/ 用测试驱动程序对用traces文件夹下所有轨迹文件进行测试;

文件包括:

amptjp-bal.rep

cccp-bal.rep    

cp-decl-bal.rep

expr-bal.rep    

coalescing-bal.rep    

random-bal.rep    

random2-bal.rep    

binary-bal.rep    

binary2-bal.rep    

realloc-bal.rep    

realloc2-bal.rep

4.2 测试结果评价

realloc使用最基本的malloc+free,即申请新块并将原块内容复制过去,没有考虑使用附近的碎片,故对realloc的测试结果较差。

另外,使用显示双向空闲链表,在链表中查找块的需要进行遍历,速度不如分离链表,故花费时间降不下来,导致thru较低。

4.3 自测试结果

如图,测试结果得分在77~83之间波动。

代码、附件github地址

https://github.com/ChenDolph7in/HITICS-LABS-in-21-Spring/tree/master/Lab8

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【HIT-计算机系统】ICS-Lab8 Dynamic Storage Allocator 的相关文章

  • ubuntu 中的 echo -e 选项不起作用

    我的同事使用Ubuntu 我使用openSUSE 我们使用相同的makefile编译相同的源代码 我的环境运行良好 但我的同事不能 总是输出无法识别 e选项 我们检查makefile 只发现echo命令使用 e option Ubuntu的
  • OS X 对 /usr/local/lib 的权限被拒绝

    我正在寻找有关权限问题的任何建议 直觉 线索 答案 自从我切换到新的 Macbook Pro 以来 这个问题一直困扰着我 这就是困境 某些程序在安装期间复制 usr local lib 下的库 并且在运行这些程序时出现崩溃 我认为这与此文件
  • 如何在 Linux 中显示进程状态(阻塞、非阻塞)

    有没有办法查询 Linux 进程表中进程的状态 以便能够演示执行查询时进程是正在运行还是被阻止 我的目标是从进程或程序的 外部 执行此操作 因为我希望从操作系统进程的角度来理解这一点 但欢迎任何想法 这是Python代码阻塞的过程 impo
  • 我如何知道用户在使用 ncurses (Linux) 的控制台中按下了 ESC 键?

    I have a problem in detecting whether I just got a plain ESC key just code 27 or whether it was another special key such
  • 如何在树莓派上更新到最新的 python 3.5.1 版本?

    我昨天拿到了 Raspberry Pi 我已经在尝试用它来编写代码了 我有一个计划在其上运行的程序 但它仅与 Python 版本 3 5 0 或 3 5 1 兼容 并且我在互联网上找到的所有内容似乎都已经过时 与 Python 2 有关 或
  • 如何从python导入路径中删除当前目录

    我想使用 Mercurial 存储库hg本身 也就是说 我克隆了 Mercurialhttps www mercurial scm org repo hg https www mercurial scm org repo hg并想运行一些h
  • malloc 实现?

    我正在尝试实施malloc and free对于C 我不知道如何重用内存 我目前有一个struct看起来像这样 typedef struct mem dictionary void addr size t size int freed me
  • BlueZ D-Bus C,应用 BLE

    我正在尝试编写一个应用程序来搜索附近的蓝牙设备并与它们通信 我的应用程序将用 C 语言编写 并打算在 Linux 下工作 是否有通过 C 中的 D Bus 使用 BlueZ 的教程或示例 此应用程序的目的是从 BLE 中的文件发送数据 你能
  • mod_perl 无法看到 /tmp 中的文件

    我有一些 mod perl 代码试图访问 tmp 下的文件 但它抛出 没有这样的文件或目录 错误 我在代码中添加了一个 ls al tmp 来查看 Perl 在目录中看到的内容 它只给了我 和 drwxrwxrwt 2 root root
  • caffe安装:opencv libpng16.so.16链接问题

    我正在尝试在 Ubuntu 14 04 机器上使用 python 接口编译 caffe 我已经安装了 Anaconda 和 opencvconda install opencv 我还安装了咖啡中规定的所有要求 并更改了注释块makefile
  • 查找当前打开的文件句柄数(不是 lsof )

    在 NIX系统上 有没有办法找出当前正在运行的进程中有多少个打开的文件句柄 我正在从正在运行的进程中寻找在 C 中使用的 API 或公式 在某些系统上 见下文 您可以在 proc pid fd 中对它们进行计数 如果不属于其中之一 请参阅下
  • PostgreSQL docker:“无法绑定 IPv6 套接字:无法分配请求的地址”

    编辑2 经过很长一段时间 解决了 请参阅下面的答案 编辑 我很遗憾地说 从昨天到今天 问题 自行 消失了 而我没有做任何事情 在这里学习很棒的非确定性课程 额外的乐趣 无法绑定 IPv6 套接字 错误仍然出现在错误日志中 因此这可能根本不是
  • 我可以告诉 Linux 不要交换特定进程的内存吗?

    有没有办法告诉 Linux 它不应该将特定进程的内存交换到磁盘 它是一个 Java 应用程序 所以理想情况下我希望有一种方法可以从命令行执行此操作 我知道您可以将全局交换性设置为 0 但这明智吗 您可以通过以下方式执行此操作姆洛克尔 2 h
  • Git - 致命:无法获取当前工作目录?

    When I git clone从回购协议中 我得到 fatal Could not get current working directory No such file or directory 我该怎么办 我检查了服务器并发现 git文
  • Tomcat 中的 403 访问被拒绝

    我有以下内容tomcat users xml
  • AMD OpenCL 在 Linux 上工作所需的最小必要文件子集是什么?

    我已经使用 buildroot 构建了 Linux 内核 我已将开源 amdgpu 驱动程序和所需的固件合并到其中 驱动程序很好 检测 GPU 模式设置运行良好 调整 小文本 的分辨率 启动后会显示命令行 现在我需要运行 OpenCL 程序
  • 串口读取未完成

    下面的函数用于在Linux下从串口读取数据 我在调试时可以读取完整的数据 但是当我启动程序时 读缓冲区似乎并不完整 我正确接收了一小部分数据 但缓冲区的其余部分完全正确zero 可能是什么问题呢 int8 t serial port ope
  • 如何使用 bash 粘贴来自单独文件的列?

    我想用分隔符 合并不同的列表 第一个列表有 2 个单词 cat first one who 第二个列表有 10000 个单词 cat second languages more simple advanced home expert tes
  • 导出多个 LD_LIBRARY_PATH 的正确方法

    对于linux的使用 我是一个新手 根据有关我的项目的指南 我必须多次导出 LD LIBRARY PATH 并且我不确定是否不覆盖它们 Cupti Tensorflow CUDAit export LD LIBRARY PATH LD LI
  • 有没有办法为向量采用内存资源?

    我已经开始在我的项目中使用 pmr allocators 并且我已经看到使用它们带来了很多性能提升和优势 我使用的分配器与我在下面的简单示例中展示的非常相似 include

随机推荐

  • 内存检测工具Dr. Memory的使用

    Dr Memory是一个内存调试工具 它是一个开源免费的内存检测工具 它能够及时发现内存相关的编程错误 比如未初始化访问 内存非法访问 数组越界读 写 以及内存泄露等 它可以在Linux Windows Mac OS和Android操作系统
  • ngrok的使用(超详细)

    1 ngrok简介 百度百科 ngrok 是一个反向代理 通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道 ngrok 可捕获和分析所有通道上的流量 便于后期分析和重放 啥玩意 1 其实说白了就是你写一个项目 在PC上完美
  • 微信小程序合法域名配置

    在微信小程序的开发过程中 当需要请求第三方网站数据时 各种教程就直接说调用wx request接口即可 但是当初学者自己用的时候就会出现问题 比如我们这里请求聚合数据的API 里边有不少免费的数据申请就可以使用 调用邮编查询的接口 getP
  • Java中的wait()与notify()/notifyAll()

    1 wait 与sleep yield 的不同 调用sleep 和yield 时 线程掌握的对象上的锁不会被释放 而调用wait 时 线程掌握的对象上的锁会被释放掉 这一点是需要注意的 也是有意义的 因为调用wait 会释放锁 所以在一个s
  • 按键从Linux到Android

    按键从Linux到Android 现在的普通按键也集成到Linux Input子系统中了 只需要把按键对应的IO端口配置好 按键就可以工作了 所以一般提供的BSP 或者叫作解决方案 中 已经完善了按键驱动 关键是快速的了解按键的映射 所以这
  • objective c 中的继承和多态简单示意(二)

    holydancer原创 如需转载 请在显要位置注明 转自holydancer的CSDN专栏 原文地址 http blog csdn net holydancer article details 7334377 OC中的继承和JAVA C
  • 剑指Offer第四十九题:把字符串转换成整数

    题目描述 将一个字符串转换成一个整数 实现Integer valueOf string 的功能 但是string不符合数字要求时返回0 要求不能使用字符串转换整数的库函数 数值为0或者字符串不是一个合法的数值则返回0 思路 判断正负什么的都
  • LeGO-LOAM论文翻译(内容精简)

    LeGO LOAM是一种在LOAM之上进行改进的激光雷达建图方法 建图效果比LOAM要好 但是建图较为稀疏 计算量也更小了 本文原地址 wykxwyc的博客 github注释后LeGO LOAM源码 LeGO LOAM NOTED 关于代码
  • C++类的介绍

    最近在学习SLAM 顺便将C 类的知识复习一下 其中部分官方定义和程序设计方法来源于西北工业大学魏英老师 1 类的定义 是用户自定义的数据类型 C 一个类定义的形式如下 class 类名 成员列表 成员列表是类成员的集合 数目可以任意多 一
  • “三国演义”何处去

    作者 朱金灿 来源 http blog csdn net clever101 微软资深副总裁张亚勤在2011移动开发者大会的演讲 移动互联的新趋势 这样描述当前的移动操作系统的分布趋势 随着Windows Phone的推出 移动平台市场渐成
  • 【Mac】mac 安装Axure RP 8 点不开 就一直跳-后闪退-报错Expected an Int64 but got a System.UInt64

    1 美图 2 概述 2 1 闪退 先确保软件已安装到 应用程序 中 比如 CleanMyMac X 软件闪退 就输入以下命令然后回车即可 如下图 codesign f s deep Applications CleanMyMac X app
  • C语言中循环结构1(求和)思路

    题目描述 求S a aa aaa aa aaa 有n个a 之值 其中a是一个数字 例如 2 22 222 2222 22222 n 5 a 2 a和n由键盘输入 思路 C语言中一个简单的循环 循环次数 循环后的sum 每循环一次 a扩大10
  • JavaWeb问题集锦: 数据库连接池请求超时 HikariPool-1 - Connection is not available, request timed out after 30000ms

    报错日志 java sql SQLTransientConnectionException HikariPool 1 Connection is not available request timed out after 30000ms 原
  • 机器学习-集成学习-梯度提升决策树(GBDT)

    目录 1 GBDT算法的过程 1 1 Boosting思想 1 2 GBDT原理 需要多少颗树 2 梯度提升和梯度下降的区别和联系是什么 3 GBDT的优点和局限性有哪些 3 1 优点 3 2 局限性 4 RF 随机森林 与GBDT之间的区
  • 更换编译器,CODE::BLOCKS 无法DEBUG 至断点

    想在LINUX下使用CODE BLOCKS 编写调试并编译连接ARM运行程序 IDE编译环境默认为 GNU GCC 编译器 修改如下 1 至Settings gt Compiler and debugger settings 将Setect
  • 互联网摸鱼日报(2023-04-19)

    互联网摸鱼日报 2023 04 19 InfoQ 热门话题 传统网关的云原生策略 InfoQ 极客有约 华为发布高阶智能驾驶系统 ADS 2 0 百度发布旗舰产品城市智驾 Apollo City Driving Max 小鹏汽车发布 SEP
  • STM32的FSMC

    FSMC之LCD彩屏学习 彩屏的驱动这里主要用到的是8080并口接口 彩屏这里有区分带有控制器和不带控制器的 80并口有如下一些信号线 CS 片选信号 WR 写数据 RD 读数据 RST 复位 RS 命令 数据标志 0 读写命令 1 读写数
  • linux常用命令整理篇4:关于tomcat的一些命令

    1 查看是否安装了 rpm qa grep tomcat 2 查看tomcat进程ID ps ef grep tomcat 3 杀死tomcat进程 kill 9 进程ID 4 查看tomcat目录 find name tomcat 5 启
  • 云笔记的使用感受和选择

    市场上有很多文章针对云笔记的选择 但经过下载发现可能存在很多虚假广告 求生欲 其实可能是个人使用感受不佳仅表示个人观点 为什么选择云笔记 个人比较喜欢 记录学习笔记和生活中的东西 之前选择有道云笔记 但因为最近打开的时候突然服务器挂了 登录
  • 【HIT-计算机系统】ICS-Lab8 Dynamic Storage Allocator

    第1章 实验基本信息 1 1 实验目的 理解现代计算机系统虚拟存储的基本知识 掌握C语言指针相关的基本操作 深入理解动态存储申请 释放的基本原理和相关系统函数 用C语言实现动态存储分配器 并进行测试分析 培养Linux下的软件系统开发与测试