当前位置:文档之家› 操作系统实验 第四讲 物理存储器与进程逻辑地址空间的管理..

操作系统实验 第四讲 物理存储器与进程逻辑地址空间的管理..

操作系统实验 第四讲 物理存储器与进程逻辑地址空间的管理..
操作系统实验 第四讲 物理存储器与进程逻辑地址空间的管理..

操作系统

实验报告

哈尔滨工程大学

计算机科学与技术学院

一、实验概述

1. 实验名称物理存储器与进程逻辑地址空间的管理

2. 实验目的通过查看物理存储器的使用情况,并练习分配和回收物理内存,

从而掌握物理存储器的管理方法。通过查看进程逻辑地址空间

的使用情况,并练习分配和回收虚拟内存,从而掌握进程逻辑地

址空间的管理方法。

3. 实验类型验证+设计

4.实验内容 3.1 准备实验

3.2 阅读控制台命令“pm”相关的源代码,并查看其执行的结果

3.3 分配物理页和释放物理页

3.4 阅读控制台命令“vm”相关的源代码,并查看其执行的结果

3.5 在系统进程中分配虚拟页和释放虚拟页

3.6 在应用程序进程中分配虚拟页和释放虚拟页

3.6.1 要求

3.6.2 测试方法

3.6.3 提示

二、实验环境

操作系统windos xp

编译器OS Lab

语言c语言

三、实验过程

1. 设计思路和流程图

MiAllocateAnyPages函数的流程图

MiFreePages函数的流程图

2.需要解决的问题及解答

(1)在实验指导的P160-4.和5.按F10单步调试MmAllocateVirtualMemory函数的执行过程,要求给出监视窗口BaseAddress和RegionSize个变量前后变化截图界面。

截图见3.5。

在实验指导的P160-1.和2. 按F10单步调试MmFreeVirtualMemory函数的执行过程,要求给出监视窗口BaseAddress和RegionSize个变量前后变化截图界面。

截图见3.5。

(2)按照《实验指导》的P160-3.6 在应用程序进程中分配虚拟页和释放虚拟页,编写代码。要求至少给出源代码及其解释。

程序见3.6.2。

(3)按F10单步调试MiAllocateAnyPages函数的执行过程,尝试回答下面的问题:

①本次分配的物理页的数量是多少?分配的物理页的页框号是多少?

②物理页是从空闲页链表中分配的?还是从零页链表中分配的?

③哪一行语句减少了空闲页的数量?哪一行语句将刚刚分配的物理页由空闲状

态修改为忙状态?

答:①本次分配的物理页的数量是1,分配的物理页的页框号是0x409;

②物理页是从空闲页链表中分配的

③第226行MiFreePageListHead=MiGetPfnDatabaseEntry(Pfn)->Next;和第227

行MiFreePageCount--;减少了空闲页的数量,第229行将刚刚分配的物理页由空闲状态修改为忙状态;

(4)按F10单步调试MiFreePages函数的执行过程,尝试回答下面的问题:

①本次释放的物理页的数量是多少?释放的物理页的页框号是多少?释放的物

理页是之前分配的物理页吗?

②释放的物理页是被放入了空闲页链表中?还是零页链表中?

③绘制MiFreePages函数的流程图。

答:①本次释放的物理页的数量是1,释放的物理页的页框号0x409,释放的物理页是之前分配的物理页;

②释放的物理页被放入了空闲页链表中;

③见实验过程开头流程图部分。

(5)按F10单步调试MmAllocateVirtualMemory函数的执行过程,尝试回答下面的问题:

①分配的虚拟页的起始地址是多少?分配的虚拟页的数量是多少?它们和参数BaseAddress和RegionSize初始化的值有什么样的关系?

②分配虚拟页的同时有为虚拟页映射实际的物理页吗?这是由哪个参数决定的?

③分配的虚拟页是在系统地址空间(高2G)还是在用户地址空间(低2G)?这是由哪个参数决定的?

④参考MiReserveAddressRegion函数的定义和注释,说明该函数的功能。

答:①分配的虚拟页的起始地址是0xa0003000,分配的虚拟页的数量是1,BaseAddress和RegionSize初始化的值是期望保留或者提交的地址区域的起始地址和大小;

②分配虚拟页的同时有为虚拟页映射实际的物理页,这是由第三个参数AllocationType决定的;

③分配的虚拟页是在系统地址空间(高2G),这是由第四个参数SystemVirtual 决定的;

④MiReserveAddressRegion函数的功能是保留一段虚拟地址区域。

(6)按F10单步调试MmFreeVirtualMemory函数的执行过程,尝试回答下面的问题:

①本次释放的虚拟地址是多少?释放的虚拟页是之前分配的虚拟页吗?

②参考MiFindReservedAddressRegion函数、MiFreeAddressRegion函数和MiDecommitPages函数的定义和注释,说明这些函数的功能。

答:①本次释放的虚拟地址是0xa0003000,是之前分配的虚拟页;

②MiFindReservedAddressRegion函数用于查找已保留地址区域,如果目标区域非已保留区域则返回失败,MiFreeAddressRegion函数用于释放已保留地址区域和MiDecommitPages函数用于释放映射在连续虚拟页框上的物理页框。

(7)在本实验

3.3中,如果分配了物理页后,没有回收,会对EOS操作系统造成什么样的影响?目前EOS操作系统内核函数MiAllocateAnyPages能处理所有物理页被分配完毕的情况吗?例如在没有可分配的物理页的情况下调用该内核函数,是否会返回失败?如果内核函数MiAllocateAnyPages还不能处理这种极端情况,尝试修改代码解决这个问题。

答:如果分配了物理页后,没有回收,将会使可分配自由页和零页越来越少,最终导致内存溢出,系统无法运行。目前EOS操作系统内核函数MiAllocateAnyPages不能处理所有物理页被分配完毕的情况,在没有可分配的物

理页的情况下,不会分配物理页,但仍然会返回成功,添加以下代码即可:Else{return STATUS_MEMORY_NOT_ALLOCATED;}

(8)在本实验 3.3 中,在分配物理页时是调用的内核函数 MiAllocateAnyPages,该函数会优先分配空闲页,尝试修改代码,调用内核函数MiAllocateZeroedPages 优先分配零页,并调试分配零页的情况。尝试从性能的角 7 度分析内核函

数 MiAllocateAnyPages 和 MiAllocateZeroedPages。尝试从安全性的角度分析分配零页的必要性。

答:将MiAllocateAnyPages(1, PfnArray);修改为

MiAllocateZeroedPages(1, PfnArray);即可。系统启动时,所有空闲物理页都是未初始化的,此时零页链表为空,MiAllocateAnyPages函数可以直接从自由页链表分配,而MiAllocateZeroedPages函数会对从自由页链表中分配的每一页进行零初始化,确保所有分配页都是被零初始化的,再进行分配,因此MiAllocateZeroedPages函数效率较低。但因为MiAllocateZeroedPages函数对自由页进行了初始化,减小了出错的可能性,从而安全性较高。

3.主要数据结构、实现代码及其说明

typedef struct _MMPFN {

ULONG Unused : 9; // 未用

ULONG PageState : 3; // 物理页的状态

ULONG Next : 20; // 下一个物理页的页框号

}MMPFN, *PMMPFN;

typedef enum _PAGE_STATE {

ZEROED_PAGE, // 零页

FREE_PAGE, // 自由页

BUSY_PAGE, // 占用页

} PAGE_STATE;

// 虚拟地址描述符

typedef struct _MMV AD{

ULONG_PTR StartingVpn; // 被使用区域的开始虚页框号

ULONG_PTR EndVpn; // 被使用区域的结束虚页框号

LIST_ENTRY VadListEntry; // 链表项,用于将描述同一地址空间的所有V AD串

//成链表

}MMV AD, *PMMV AD;

// 虚拟地址表

typedef struct _MMV AD_LIST{

ULONG_PTR StartingVpn; // 记录的进程地址空间的开始虚页号

ULONG_PTR EndVpn; // 记录的进程地址空间的结束虚页号

LIST_ENTRY VadListHead; // V AD链表头

}MMV AD_LIST, *PMMV AD_LIST;

4.程序运行时的初值和运行结果

3.1准备实验

1. 启动 OS Lab。

2. 新建一个 EOS Kernel 项目。

3.2阅读控制台命令“pm”相关的源代码,并查看其执行的结果

执行控制台命令“ pm”,查看物理存储器的信息:

3.3分配物理页和释放物理页

使用pm.c 文件中 ConsoleCmdPhysicalMemory 函数的函数体替换 ke/sysproc.c 文件中ConsoleCmdPhysicalMemory 函数的函数体。调试并执行控制台命令“ pm”,查看物理存储器的信息:

分配和释放多个物理页

调用 MiAllocateAnyPages 函数时分配多个物理页,然后在调用 MiFreePages 函数时将分配的多个物理页释放。

3.4阅读控制台命令“vm”相关的源代码,并查看其执行的结果

执行控制台命令“ vm”,查看系统进程的虚拟地址描述符信息:按 F5 启动调试。

待 EOS 启动完毕,在 EOS 控制台中输入命令“pt”后按回车。“pt”命令可以输出当前系统中的进程列表,其中系统进程的 ID 为 1。

在 EOS 控制台中输入命令“ vm 1”后按回车得到虚拟地址描述符信息。

执行控制台命令“ vm”,查看当创建了一个应用程序进程后,系统进程和应用程序进程中虚拟地址描述符的信息:

切换到“Console-2”,然后输入命令“ pt”后按回车。输出的信息:

输入命令“ vm 1”后按回车,可以查看系统进程中虚拟地址描述符的信息

输入命令“ vm 31”后按回车,可以查看应用程序进程中虚拟地址描述符的信息

3.5在系统进程中分配虚拟页和释放虚拟页

使用vm.c 文件中 ConsoleCmdVM 函数的函数体替换 ke/sysproc.c 文件中ConsoleCmdVM 函数的函数体。在 EOS 控制台中输入命令“vm 1”后按回车

调试分配虚拟页和释放虚拟页的过程:vm 命令开始执行后,会在调用MmAllocateVirtualMemory 函数的代码行处中断。此时要注意参数BaseAddress 和 RegionSize 初始化的值。

分配虚拟页的调试过程中BaseAddress 和RegionSize 的值的变化:

进入函数之前BaseAddress 和RegionSize 的值

退出函数以后BaseAddress 和RegionSize 的值

进入函数前BaseAddress 和RegionSize 的值

刚退出函数时BaseAddress 和RegionSize 的值

在调用 MmAllocateVirtualMemory 函数时将 RegionSize 参数的值设置为PAGE_SIZE+1时“输出”窗口中转储的信息:

Total Vpn from 655360 to 657407. (0xA0000000 - 0xA07FFFFF)

1# Vad Include 1 Vpn From 655360 to 655360. (0xA0000000 - 0xA0000FFF)

2# Vad Include 2 Vpn From 655361 to 655362. (0xA0001000 - 0xA0002FFF)

3# Vad Include 2 Vpn From 655365 to 655366. (0xA0005000 - 0xA0006FFF)

4# Vad Include 2 Vpn From 655367 to 655368. (0xA0007000 - 0xA0008FFF)

5# Vad Include 2 Vpn From 655369 to 655370. (0xA0009000 - 0xA000AFFF)

6# Vad Include 2 Vpn From 655371 to 655372. (0xA000B000 - 0xA000CFFF)

7# Vad Include 2 Vpn From 655373 to 655374. (0xA000D000 - 0xA000EFFF)

8# Vad Include 2 Vpn From 655375 to 655376. (0xA000F000 - 0xA0010FFF)

9# Vad Include 2 Vpn From 655377 to 655378. (0xA0011000 - 0xA0012FFF)

10# Vad Include 2 Vpn From 655379 to 655380. (0xA0013000 - 0xA0014FFF)

11# Vad Include 2 Vpn From 655381 to 655382. (0xA0015000 - 0xA0016FFF)

Total Vpn Count: 2048.

Allocated Vpn Count: 21.

Free Vpn Count: 2027.

Zeroed Physical Page Count: 0.

Free Physical Page Count: 7126.

New VM's base address: 0xA0017000. Size: 0x3000.

1# Vad Include 1 Vpn From 655360 to 655360. (0xA0000000 - 0xA0000FFF)

2# Vad Include 2 Vpn From 655361 to 655362. (0xA0001000 - 0xA0002FFF)

3# Vad Include 2 Vpn From 655365 to 655366. (0xA0005000 - 0xA0006FFF)

4# Vad Include 2 Vpn From 655367 to 655368. (0xA0007000 - 0xA0008FFF)

5# Vad Include 2 Vpn From 655369 to 655370. (0xA0009000 - 0xA000AFFF)

6# Vad Include 2 Vpn From 655371 to 655372. (0xA000B000 - 0xA000CFFF)

7# Vad Include 2 Vpn From 655373 to 655374. (0xA000D000 - 0xA000EFFF)

8# Vad Include 2 Vpn From 655375 to 655376. (0xA000F000 - 0xA0010FFF)

9# Vad Include 2 Vpn From 655377 to 655378. (0xA0011000 - 0xA0012FFF)

10# Vad Include 2 Vpn From 655379 to 655380. (0xA0013000 - 0xA0014FFF)

11# Vad Include 2 Vpn From 655381 to 655382. (0xA0015000 - 0xA0016FFF)

12# Vad Include 3 Vpn From 655383 to 655385. (0xA0017000 - 0xA0019FFF)

Allocated Vpn Count: 24.

Free Vpn Count: 2024.

Zeroed Physical Page Count: 0.

Free Physical Page Count: 7126.

Free VM's base address: 0xA0017000. Size: 0x3000.

1# Vad Include 1 Vpn From 655360 to 655360. (0xA0000000 - 0xA0000FFF)

2# Vad Include 2 Vpn From 655361 to 655362. (0xA0001000 - 0xA0002FFF)

3# Vad Include 2 Vpn From 655365 to 655366. (0xA0005000 - 0xA0006FFF)

4# Vad Include 2 Vpn From 655367 to 655368. (0xA0007000 - 0xA0008FFF)

5# Vad Include 2 Vpn From 655369 to 655370. (0xA0009000 - 0xA000AFFF)

6# Vad Include 2 Vpn From 655371 to 655372. (0xA000B000 - 0xA000CFFF)

7# Vad Include 2 Vpn From 655373 to 655374. (0xA000D000 - 0xA000EFFF)

8# Vad Include 2 Vpn From 655375 to 655376. (0xA000F000 - 0xA0010FFF)

9# Vad Include 2 Vpn From 655377 to 655378. (0xA0011000 - 0xA0012FFF)

10# Vad Include 2 Vpn From 655379 to 655380. (0xA0013000 - 0xA0014FFF)

11# Vad Include 2 Vpn From 655381 to 655382. (0xA0015000 - 0xA0016FFF)

Allocated Vpn Count: 21.

Free Vpn Count: 2027.

Zeroed Physical Page Count: 0.

Free Physical Page Count: 7126.

在调用 MmAllocateVirtualMemory 函数时将 BaseAddress 参数的值设置为已经被占用的虚拟内存,例如 0xA0000000,“输出”窗口中转储的信息:

Total Vpn from 655360 to 657407. (0xA0000000 - 0xA07FFFFF)

1# Vad Include 1 Vpn From 655360 to 655360. (0xA0000000 - 0xA0000FFF) 2# Vad Include 2 Vpn From 655361 to 655362. (0xA0001000 - 0xA0002FFF) 3# Vad Include 2 Vpn From 655365 to 655366. (0xA0005000 - 0xA0006FFF) 4# Vad Include 2 Vpn From 655367 to 655368. (0xA0007000 - 0xA0008FFF) 5# Vad Include 2 Vpn From 655369 to 655370. (0xA0009000 - 0xA000AFFF) 6# Vad Include 2 Vpn From 655371 to 655372. (0xA000B000 - 0xA000CFFF) 7# Vad Include 2 Vpn From 655373 to 655374. (0xA000D000 - 0xA000EFFF) 8# Vad Include 2 Vpn From 655375 to 655376. (0xA000F000 - 0xA0010FFF) 9# Vad Include 2 Vpn From 655377 to 655378. (0xA0011000 - 0xA0012FFF) 10# Vad Include 2 Vpn From 655379 to 655380. (0xA0013000 - 0xA0014FFF) 11# Vad Include 2 Vpn From 655381 to 655382. (0xA0015000 - 0xA0016FFF)

Total Vpn Count: 2048.

Free Vpn Count: 2027.

Zeroed Physical Page Count: 0.

Free Physical Page Count: 7126.

New VM's base address: 0xA0003000. Size: 0x1000.

1# Vad Include 1 Vpn From 655360 to 655360. (0xA0000000 - 0xA0000FFF) 2# Vad Include 2 Vpn From 655361 to 655362. (0xA0001000 - 0xA0002FFF) 3# Vad Include 1 Vpn From 655363 to 655363. (0xA0003000 - 0xA0003FFF) 4# Vad Include 2 Vpn From 655365 to 655366. (0xA0005000 - 0xA0006FFF) 5# Vad Include 2 Vpn From 655367 to 655368. (0xA0007000 - 0xA0008FFF) 6# Vad Include 2 Vpn From 655369 to 655370. (0xA0009000 - 0xA000AFFF) 7# Vad Include 2 Vpn From 655371 to 655372. (0xA000B000 - 0xA000CFFF) 8# Vad Include 2 Vpn From 655373 to 655374. (0xA000D000 - 0xA000EFFF) 9# Vad Include 2 Vpn From 655375 to 655376. (0xA000F000 - 0xA0010FFF) 10# Vad Include 2 Vpn From 655377 to 655378. (0xA0011000 - 0xA0012FFF) 11# Vad Include 2 Vpn From 655379 to 655380. (0xA0013000 - 0xA0014FFF) 12# Vad Include 2 Vpn From 655381 to 655382. (0xA0015000 - 0xA0016FFF)

Free Vpn Count: 2026.

Zeroed Physical Page Count: 0.

Free Physical Page Count: 7126.

Free VM's base address: 0xA0003000. Size: 0x1000.

1# Vad Include 1 Vpn From 655360 to 655360. (0xA0000000 - 0xA0000FFF)

2# Vad Include 2 Vpn From 655361 to 655362. (0xA0001000 - 0xA0002FFF)

3# Vad Include 2 Vpn From 655365 to 655366. (0xA0005000 - 0xA0006FFF)

4# Vad Include 2 Vpn From 655367 to 655368. (0xA0007000 - 0xA0008FFF)

5# Vad Include 2 Vpn From 655369 to 655370. (0xA0009000 - 0xA000AFFF)

6# Vad Include 2 Vpn From 655371 to 655372. (0xA000B000 - 0xA000CFFF)

7# Vad Include 2 Vpn From 655373 to 655374. (0xA000D000 - 0xA000EFFF)

8# Vad Include 2 Vpn From 655375 to 655376. (0xA000F000 - 0xA0010FFF)

9# Vad Include 2 Vpn From 655377 to 655378. (0xA0011000 - 0xA0012FFF)

10# Vad Include 2 Vpn From 655379 to 655380. (0xA0013000 - 0xA0014FFF)

11# Vad Include 2 Vpn From 655381 to 655382. (0xA0015000 - 0xA0016FFF)

Free Vpn Count: 2027.

Free Physical Page Count: 7126.

在调用 MmAllocateVirtualMemory 函数时将 RegionSize 参数的值设置为

PAGE_SIZE*2,将BaseAddress 参数的值设置为 0xA0017004,“输出”窗口中转储的信息:

Total Vpn from 655360 to 657407. (0xA0000000 - 0xA07FFFFF)

1# Vad Include 1 Vpn From 655360 to 655360. (0xA0000000 - 0xA0000FFF)

2# Vad Include 2 Vpn From 655361 to 655362. (0xA0001000 - 0xA0002FFF)

3# Vad Include 2 Vpn From 655365 to 655366. (0xA0005000 - 0xA0006FFF)

4# Vad Include 2 Vpn From 655367 to 655368. (0xA0007000 - 0xA0008FFF)

5# Vad Include 2 Vpn From 655369 to 655370. (0xA0009000 - 0xA000AFFF)

6# Vad Include 2 Vpn From 655371 to 655372. (0xA000B000 - 0xA000CFFF)

7# Vad Include 2 Vpn From 655373 to 655374. (0xA000D000 - 0xA000EFFF)

8# Vad Include 2 Vpn From 655375 to 655376. (0xA000F000 - 0xA0010FFF)

9# Vad Include 2 Vpn From 655377 to 655378. (0xA0011000 - 0xA0012FFF)

10# Vad Include 2 Vpn From 655379 to 655380. (0xA0013000 - 0xA0014FFF)

11# Vad Include 2 Vpn From 655381 to 655382. (0xA0015000 - 0xA0016FFF)

Total Vpn Count: 2048.

Allocated Vpn Count: 21.

Free Vpn Count: 2027.

Zeroed Physical Page Count: 0.

Free Physical Page Count: 7126.

New VM's base address: 0xA0017000. Size: 0x3000.

1# Vad Include 1 Vpn From 655360 to 655360. (0xA0000000 - 0xA0000FFF) 2# Vad Include 2 Vpn From 655361 to 655362. (0xA0001000 - 0xA0002FFF) 3# Vad Include 2 Vpn From 655365 to 655366. (0xA0005000 - 0xA0006FFF) 4# Vad Include 2 Vpn From 655367 to 655368. (0xA0007000 - 0xA0008FFF) 5# Vad Include 2 Vpn From 655369 to 655370. (0xA0009000 - 0xA000AFFF) 6# Vad Include 2 Vpn From 655371 to 655372. (0xA000B000 - 0xA000CFFF) 7# Vad Include 2 Vpn From 655373 to 655374. (0xA000D000 - 0xA000EFFF) 8# Vad Include 2 Vpn From 655375 to 655376. (0xA000F000 - 0xA0010FFF) 9# Vad Include 2 Vpn From 655377 to 655378. (0xA0011000 - 0xA0012FFF) 10# Vad Include 2 Vpn From 655379 to 655380. (0xA0013000 - 0xA0014FFF) 11# Vad Include 2 Vpn From 655381 to 655382. (0xA0015000 - 0xA0016FFF) 12# Vad Include 3 Vpn From 655383 to 655385. (0xA0017000 - 0xA0019FFF)

Free Vpn Count: 2024.

Zeroed Physical Page Count: 0.

Free Physical Page Count: 7126.

Free VM's base address: 0xA0017000. Size: 0x3000.

1# Vad Include 1 Vpn From 655360 to 655360. (0xA0000000 - 0xA0000FFF) 2# Vad Include 2 Vpn From 655361 to 655362. (0xA0001000 - 0xA0002FFF) 3# Vad Include 2 Vpn From 655365 to 655366. (0xA0005000 - 0xA0006FFF) 4# Vad Include 2 Vpn From 655367 to 655368. (0xA0007000 - 0xA0008FFF) 5# Vad Include 2 Vpn From 655369 to 655370. (0xA0009000 - 0xA000AFFF) 6# Vad Include 2 Vpn From 655371 to 655372. (0xA000B000 - 0xA000CFFF) 7# Vad Include 2 Vpn From 655373 to 655374. (0xA000D000 - 0xA000EFFF) 8# Vad Include 2 Vpn From 655375 to 655376. (0xA000F000 - 0xA0010FFF) 9# Vad Include 2 Vpn From 655377 to 655378. (0xA0011000 - 0xA0012FFF) 10# Vad Include 2 Vpn From 655379 to 655380. (0xA0013000 - 0xA0014FFF) 11# Vad Include 2 Vpn From 655381 to 655382. (0xA0015000 - 0xA0016FFF)

Free Vpn Count: 2027.

Zeroed Physical Page Count: 0.

3.6在应用程序进程中分配虚拟页和释放虚拟页

3.6.1要求

创建一个 EOS 应用程序,并编写代码完成下列功能:

1. 调用 API 函数 VirtualAlloc,分配一个整型变量所需的空间,并使用一个整型变量的指针指向这

个空间。

2. 修改整型变量的值为 0xFFFFFFFF。在修改前输出整型变量的值,在修改后再输出整型变量的值。

3. 调用 API 函数 Sleep,等待 10 秒钟。

4. 调用 API 函数 VirtualFree,释放之前分配的整型变量的空间。

5. 进入死循环,这样应用程序就不会结束。

3.6.2编写的代码:

#include "EOSApp.h"

int main(int argc, char* argv[])

{

#ifdef _DEBUG

__asm("int $3\n nop");

#endif

INT *d;

/*

调用API 函数VirtualAlloc,分配一个整型变量所需的空间,并使用一个整型变量的指针指向这个空间。

*/

if(d=VirtualAlloc(0,sizeof(int),MEM_RESERVE|MEM_COMMIT)){

printf("Allocated %d bytes virtual memory of 0x%x\n\n",*d);

/*

修改整型变量的值为0xFFFFFFFF。在修改前输出整型变量的值,在修改后再输出整型变量的值*/

printf("virtual memory original value :0x%x \n\n",*d);

*d=0xFFFFFFFF;

printf("a new virtual memory value :0x%x \n\n",*d);

printf("\nWait for 10 seconds\n");

Sleep(10000);

/*

调用API函数Sleep等待10秒钟。

*/

if(VirtualFree(d,0,MEM_RELEASE))

/*

调用API函数VirtualFree,释放之前分配的整型变量的空间。

*/

printf("\nRelease virtual memory sucess!\n");

else

printf("release error\n");

printf("endless loop");

/*

进入死循环,这样应用程序就不会结束。

*/

for(;;);}

else {

printf("error\n");

return -1;}

printf("Hello world!\n");

return 0;

}

运行结果:

在应用程序进程中分配虚拟页和释放虚拟页

分配虚拟页后和释放虚拟页后,应用程序进程的虚拟地址描述符信息

计算机操作系统进程调度实验研究报告

计算机操作系统进程调度实验研究报告

————————————————————————————————作者:————————————————————————————————日期:

操作系统实验题:设计一若干并发进程的进程调度程序 一、实验目的 无论是批处理系统、分时系统还是实时系统,用户进程数一般都大于处理机数,这将导致用户进程互相争夺处理机。这就要求进程调度程序按一定的策略,动态地把处理及分配给处于就绪队列中的某一进程,以使之执行。进程调度是处理机管理的核心内容。本实验要求采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法编写和调试一个简单的进程调度程序。通过本实验可以加深理解有关进程控制块、进程队列的概念。并体会了优先数和先来先服务调度算法的具体实施办法。 二、实验要求 用高级语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解. 三、实验内容 进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法(将用户作业和就绪进程按提交顺序或变为就绪状态的先后排成队列,并按照先来先服务的方式进行调度处理)。 每个进程有一个进程控制块(PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。 进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。进程的到达时间为进程输入的时间。 进程的运行时间以时间片为单位进行计算。 每个进程的状态可以是就绪W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。 就绪进程获得CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。 如果运行一个时间片后,进程的已占用CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。 每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的PCB,以便进行检查。重复以上过程,直到所要进程都完成为止。 四、实验算法流程

2014-2015(1)操作系统实验

实验项目名称:进程的同步(实验一) 1、实验目的 (1) 掌握进程和线程基本概念和属性; (2) 掌握用PV操作解决并发进程的同步问题; (3) 掌握用于同步的信号量初值的设置; (4) 掌握如何处理共享资源的直接制约关系。 2、实验内容 (1) 设计一个模拟若干售票网点的售票程序。界面可以参考图1。还应设计多个后台售票线程并发运行。 图1售票 (2) 模拟:桌上有一只盘子,每次只能放入一个水果。爸爸专向盘子中放苹果,妈妈专向盘子中放桔子,一个女儿专等吃盘子里的苹果,一个儿子专等吃盘子里的桔子。只要盘子空则爸爸或妈妈都可以向盘子放一个水果,仅当盘子中有自己需要的水果时,儿子或女儿可以从盘子中取出水果。放-取水果的几种情况如图2(a)~(f)所示,可以参照进行设计。 (a)盘子空时取水果 (b)父亲放入苹果

(c) 儿子取水果 (d) 女儿取水果 (e)儿子取走桔子 (f)盘子满时放水果 图2 放-取水果 (3) 自选其它能反映进程互斥问题的应用。 实验项目名称:处理机调度(实验二) 1、实验目的 (1) 掌握几种处理机调度算法的基本思想和特点; (2) 理解并发与并行的区别; (3) 比较几种算法的特点。 2、实验内容 编写程序模拟处理机调度,参照图3。 (1) 时间片轮转 (2) 动态优先权调度 (3) 高响应比优先调度

图3 模拟处理机调度 实验项目名称:银行家算法(实验三) 1、实验目的 银行家算法是避免死锁的一种重要方法,本实验要求用高级语言编写和调试一个简单的银行家算法程序。加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。 2、实验内容 (1) 设计进程对各类资源最大申请表示及初值确定。 (2) 设定系统提供资源初始状况。 (3) 设定每次某个进程对各类资源的申请表示。 (4) 编制程序,依据银行家算法,决定其申请是否得到满足。 具体设计可参照图4(a)~(c) 进行。

操作系统内存管理复习过程

操作系统内存管理

操作系统内存管理 1. 内存管理方法 内存管理主要包括虚地址、地址变换、内存分配和回收、内存扩充、内存共享和保护等功能。 2. 连续分配存储管理方式 连续分配是指为一个用户程序分配连续的内存空间。连续分配有单一连续存储管理和分区式储管理两种方式。 2.1 单一连续存储管理 在这种管理方式中,内存被分为两个区域:系统区和用户区。应用程序装入到用户区,可使用用户区全部空间。其特点是,最简单,适用于单用户、单任务的操作系统。CP/M和 DOS 2.0以下就是采用此种方式。这种方式的最大优点就是易于管理。但也存在着一些问题和不足之处,例如对要求内

存空间少的程序,造成内存浪费;程序全部装入,使得很少使用的程序部分也占用—定数量的内存。 2.2 分区式存储管理 为了支持多道程序系统和分时系统,支持多个程序并发执行,引入了分区式存储管理。分区式存储管理是把内存分为一些大小相等或不等的分区,操作系统占用其中一个分区,其余的分区由应用程序使用,每个应用程序占用一个或几个分区。分区式存储管理虽然可以支持并发,但难以进行内存分区的共享。 分区式存储管理引人了两个新的问题:内碎片和外碎片。 内碎片是占用分区内未被利用的空间,外碎片是占用分区之间难以利用的空闲分区(通常是小空闲分区)。 为实现分区式存储管理,操作系统应维护的数据结构为分区表或分区链表。表中各表项一般包括每个分区的起始地址、大小及状态(是否已分配)。

分区式存储管理常采用的一项技术就是内存紧缩(compaction)。 2.2.1 固定分区(nxedpartitioning)。 固定式分区的特点是把内存划分为若干个固定大小的连续分区。分区大小可以相等:这种作法只适合于多个相同程序的并发执行(处理多个类型相同的对象)。分区大小也可以不等:有多个小分区、适量的中等分区以及少量的大分区。根据程序的大小,分配当前空闲的、适当大小的分区。 优点:易于实现,开销小。 缺点主要有两个:内碎片造成浪费;分区总数固定,限制了并发执行的程序数目。 2.2.2动态分区(dynamic partitioning)。 动态分区的特点是动态创建分区:在装入程序时按其初始要求分配,或在其执行过程中通过系统调用进行分配或改变分区大小。与固定分区相比较其优点是:没有内碎

操作系统实验-进程控制

实验一、进程控制实验 1.1 实验目的 加深对于进程并发执行概念的理解。实践并发进程的创建和控制方法。观察和体验进程的动态特性。进一步理解进程生命期期间创建、变换、撤销状态变换的过程。掌握进程控制的方法,了解父子进程间的控制和协作关系。练习Linux 系统中进程创建与控制有关的系统调用的编程和调试技术。 1.2 实验说明 1)与进程创建、执行有关的系统调用说明进程可以通过系统调用fork()创建子进程并和其子进程并发执行.子进程初始的执行映像是父进程的一个复本.子进程可以通过exec()系统调用族装入一个新的执行程序。父进程可以使用wait()或waitpid()系统调用等待子进程的结束并负责收集和清理子进程的退出状态。 fork()系统调用语法: #include pid_t fork(void); fork 成功创建子进程后将返回子进程的进程号,不成功会返回-1. exec 系统调用有一组6 个函数,其中示例实验中引用了execve 系统调用语法: #include int execve(const char *path, const char *argv[], const char * envp[]); path 要装入 的新的执行文件的绝对路径名字符串. argv[] 要传递给新执行程序的完整的命令参数列表(可以为空). envp[] 要传递给新执行程序的完整的环境变量参数列表(可以为空).

Exec 执行成功后将用一个新的程序代替原进程,但进程号不变,它绝不会再返回到调用进程了。如果exec 调用失败,它会返回-1。 wait() 系统调用语法: #include #include pid_t wait(int *status); pid_t waitpid(pid_t pid,int *status,int option); status 用 于保留子进程的退出状态 pid 可以为以下可能值: -1 等待所有PGID 等于PID 的绝对值的子进程 1 等待所有子进程 0 等待所有PGID 等于调用进程的子进程 >0 等待PID 等于pid 的子进程option 规 定了调用waitpid 进程的行为: WNOHANG 没有子进程时立即返回 WUNTRACED 没有报告状态的进程时返回 wait 和waitpid 执行成功将返回终止的子进程的进程号,不成功返回-1。 getpid()系统调用语法: #include #include pid_t getpid(void); pid_t getppid(void); getpid 返回当前进程的进程号,getppid 返回当前进程父进程的进程号 2)与进程控制有关的系统调用说明可以通过信号向一个进程发送消息以控制进程的 行为。信号是由中断或异常事件引发的,如:键盘中断、定时器中断、非法内存引

操作系统实验内存分配

西安邮电大学 (计算机学院) 课内实验报告 实验名称:内存管理 专业名称:软件工程 班级: 学生姓名: 学号(8位): 指导教师: 实验日期:

实验五:进程 1.实验目的 通过深入理解区管理的三种算法,定义相应的数据结构,编写具体代码。充分模拟三种算法的实现过程,并通过对比,分析三种算法的优劣。 (1)掌握内存分配FF,BF,WF策略及实现的思路; (2)掌握内存回收过程及实现思路; (3)参考给出的代码思路,实现内存的申请、释放的管理程序,调试运行,总结程序设计中出现的问题并找出原因,写出实验报告。 2.实验要求: 1)掌握内存分配FF,BF,WF策略及实现的思路; 2)掌握内存回收过程及实现思路; 3)参考本程序思路,实现内存的申请、释放的管理程序,调试运行,总结程序设计中出现的问题并找出原因,写出实验报告。 3.实验过程: 创建进程:

删除其中几个进程:(默认以ff首次适应算法方式排列) Bf最佳适应算法排列方式:

wf最差匹配算法排列方式: 4.实验心得: 这次实验实验时间比较长,而且实验指导书中对内存的管理讲的很详细,老师上课的时候也有讲的很详细,但是代码比较长,刚开始的时候也是不太懂,但是后面经过和同学一起商讨,明白几种算法的含义: ①首次适应算法。在采用空闲分区链作为数据结构时,该算法要求空闲分区链表以地址递增的次序链接。在进行内存分配时,从链首开始顺序查找,直至找到一个能满足进程大小要求的空闲分区为止。然后,再按照进程请求内存的大小,从该分区中划出一块内存空间分配给请求进程,余下的空闲分区仍留在空闲链中。 ②循环首次适应算法。该算法是由首次适应算法演变而形成的,在为进程分配内存空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直至找到第一个能满足要求的空闲分区,并从中划出一块与请求的大小相等的内存空间分配给进程。 ③最佳适应算法将空闲分区链表按分区大小由小到大排序,在链表中查找第一个满足要求的分区。 ④最差匹配算法将空闲分区链表按分区大小由大到小排序,在链表中找到第一个满足要求的空闲分区。 实验中没有用到循环首次适应算法,但是对其他三种的描述还是很详细,总的来说,从实验中还是学到了很多。 5.程序源代码: #include #include #include

操作系统实验之内存管理实验报告

学生学号 实验课成绩 武汉理工大学 学生实验报告书 实验课程名称 计算机操作系统 开 课 学 院 计算机科学与技术学院 指导老师姓名 学 生 姓 名 学生专业班级 2016 — 2017 学年第一学期

实验三 内存管理 一、设计目的、功能与要求 1、实验目的 掌握内存管理的相关内容,对内存的分配和回收有深入的理解。 2、实现功能 模拟实现内存管理机制 3、具体要求 任选一种计算机高级语言编程实现 选择一种内存管理方案:动态分区式、请求页式、段式、段页式等 能够输入给定的内存大小,进程的个数,每个进程所需内存空间的大小等 能够选择分配、回收操作 内购显示进程在内存的储存地址、大小等 显示每次完成内存分配或回收后内存空间的使用情况 二、问题描述 所谓分区,是把内存分为一些大小相等或不等的分区,除操作系统占用一个分区外,其余分区用来存放进程的程序和数据。本次实验中才用动态分区法,也就是在作业的处理过程中划分内存的区域,根据需要确定大小。 动态分区的分配算法:首先从可用表/自由链中找到一个足以容纳该作业的可用空白区,如果这个空白区比需求大,则将它分为两个部分,一部分成为已分配区,剩下部分仍为空白区。最后修改可用表或自由链,并回送一个所分配区的序号或该分区的起始地址。 最先适应法:按分区的起始地址的递增次序,从头查找,找到符合要求的第一个分区。

最佳适应法:按照分区大小的递增次序,查找,找到符合要求的第一个分区。 最坏适应法:按分区大小的递减次序,从头查找,找到符合要求的第一个分区。 三、数据结构及功能设计 1、数据结构 定义空闲分区结构体,用来保存内存中空闲分区的情况。其中size属性表示空闲分区的大小,start_addr表示空闲分区首地址,next指针指向下一个空闲分区。 //空闲分区 typedef struct Free_Block { int size; int start_addr; struct Free_Block *next; } Free_Block; Free_Block *free_block; 定义已分配的内存空间的结构体,用来保存已经被进程占用了内存空间的情况。其中pid作为该被分配分区的编号,用于在释放该内存空间时便于查找。size表示分区的大小,start_addr表示分区的起始地址,process_name存放进程名称,next指针指向下一个分区。 //已分配分区的结构体 typedef struct Allocate_Block { int pid; int size; int start_addr; char process_name[PROCESS_NAME_LEN]; struct Allocate_Block *next; } Allocate_Block; 2、模块说明 2.1 初始化模块 对内存空间进行初始化,初始情况内存空间为空,但是要设置内存的最大容量,该内存空间的首地址,以便之后新建进程的过程中使用。当空闲分区初始化

操作系统实验报告--实验一--进程管理

实验一进程管理 一、目的 进程调度是处理机管理的核心内容。本实验要求编写和调试一个简单的进程调度程序。通过本实验加深理解有关进程控制块、进程队列的概念,并体会和了解进程调度算法的具体实施办法。 二、实验内容及要求 1、设计进程控制块PCB的结构(PCB结构通常包括以下信息:进程名(进程ID)、进程优先数、轮转时间片、进程所占用的CPU时间、进程的状态、当前队列指针等。可根据实验的不同,PCB结构的内容可以作适当的增删)。为了便于处理,程序中的某进程运行时间以时间片为单位计算。各进程的轮转时间数以及进程需运行的时间片数的初始值均由用户给定。 2、系统资源(r1…r w),共有w类,每类数目为r1…r w。随机产生n进程P i(id,s(j,k),t),0<=i<=n,0<=j<=m,0<=k<=dt为总运行时间,在运行过程中,会随机申请新的资源。 3、每个进程可有三个状态(即就绪状态W、运行状态R、等待或阻塞状态B),并假设初始状态为就绪状态。建立进程就绪队列。 4、编制进程调度算法:时间片轮转调度算法 本程序用该算法对n个进程进行调度,进程每执行一次,CPU时间片数加1,进程还需要的时间片数减1。在调度算法中,采用固定时间片(即:每执行一次进程,该进程的执行时间片数为已执行了1个单位),这时,CPU时间片数加1,进程还需要的时间片数减1,并排列到就绪队列的尾上。 三、实验环境 操作系统环境:Windows系统。 编程语言:C#。 四、实验思路和设计 1、程序流程图

2、主要程序代码 //PCB结构体 struct pcb { public int id; //进程ID public int ra; //所需资源A的数量 public int rb; //所需资源B的数量 public int rc; //所需资源C的数量 public int ntime; //所需的时间片个数 public int rtime; //已经运行的时间片个数 public char state; //进程状态,W(等待)、R(运行)、B(阻塞) //public int next; } ArrayList hready = new ArrayList(); ArrayList hblock = new ArrayList(); Random random = new Random(); //ArrayList p = new ArrayList(); int m, n, r, a,a1, b,b1, c,c1, h = 0, i = 1, time1Inteval;//m为要模拟的进程个数,n为初始化进程个数 //r为可随机产生的进程数(r=m-n) //a,b,c分别为A,B,C三类资源的总量 //i为进城计数,i=1…n //h为运行的时间片次数,time1Inteval为时间片大小(毫秒) //对进程进行初始化,建立就绪数组、阻塞数组。 public void input()//对进程进行初始化,建立就绪队列、阻塞队列 { m = int.Parse(textBox4.Text); n = int.Parse(textBox5.Text); a = int.Parse(textBox6.Text); b = int.Parse(textBox7.Text); c = int.Parse(textBox8.Text); a1 = a; b1 = b; c1 = c; r = m - n; time1Inteval = int.Parse(textBox9.Text); timer1.Interval = time1Inteval; for (i = 1; i <= n; i++) { pcb jincheng = new pcb(); jincheng.id = i; jincheng.ra = (random.Next(a) + 1); jincheng.rb = (random.Next(b) + 1); jincheng.rc = (random.Next(c) + 1); jincheng.ntime = (random.Next(1, 5)); jincheng.rtime = 0;

第四章 操作系统存储管理(练习题)

第四章存储管理 1. C存储管理支持多道程序设计,算法简单,但存储碎片多。 A. 段式 B. 页式 C. 固定分区 D. 段页式 2.虚拟存储技术是 B 。 A. 补充内存物理空间的技术 B. 补充相对地址空间的技术 C. 扩充外存空间的技术 D. 扩充输入输出缓冲区的技术 3.虚拟内存的容量只受 D 的限制。 A. 物理内存的大小 B. 磁盘空间的大小 C. 数据存放的实际地址 D. 计算机地址位数 4.动态页式管理中的 C 是:当内存中没有空闲页时,如何将已占据的页释放。 A. 调入策略 B. 地址变换 C. 替换策略 D. 调度算法 5.多重分区管理要求对每一个作业都分配 B 的内存单元。 A. 地址连续 B. 若干地址不连续 C. 若干连续的帧 D. 若干不连续的帧 6.段页式管理每取一数据,要访问 C 次内存。 A. 1 B. 2 C. 3 D. 4 7.分段管理提供 B 维的地址结构。 A. 1 B. 2 C. 3 D. 4 8.系统抖动是指 B。 A. 使用计算机时,屏幕闪烁的现象 B. 刚被调出内存的页又立刻被调入所形成的频繁调入调出的现象 C. 系统盘不干净,操作系统不稳定的现象 D. 由于内存分配不当,造成内存不够的现象 9.在 A中,不可能产生系统抖动现象。 A. 静态分区管理 B. 请求分页式管理 C. 段式存储管理 D. 段页式存储管理 10.在分段管理中 A 。 A. 以段为单元分配,每段是一个连续存储区 B. 段与段之间必定不连续 C. 段与段之间必定连续 D. 每段是等长的 11.请求分页式管理常用的替换策略之一有 A 。 A. LRU B. BF C. SCBF D. FPF 12.可由CPU调用执行的程序所对应的地址空间为 D 。 A. 名称空间 B. 虚拟地址空间 C. 相对地址空间 D. 物理地址空间 13. C 存储管理方式提供二维地址结构。 A. 固定分区 B. 分页

操作系统课程设计内存管理

内存管理模拟 实验目标: 本实验的目的是从不同侧面了解Windows 2000/XP 对用户进程的虚拟内存空间的管理、分配方法。同时需要了解跟踪程序的编写方法(与被跟踪程序保持同步,使用Windows提供的信号量)。对Windows分配虚拟内存、改变内存状态,以及对物理内存(physical memory)和页面文件(pagefile)状态查询的API 函数的功能、参数限制、使用规则要进一步了解。 默认情况下,32 位Windows 2000/XP 上每个用户进程可以占有2GB 的私有地址空间,操作系统占有剩下的2GB。Windows 2000/XP 在X86 体系结构上利用二级页表结构来实现虚拟地址向物理地址的变换。一个32 位虚拟地址被解释为三个独立的分量——页目录索引、页表索引和字节索引——它们用于找出描述页面映射结构的索引。页面大小及页表项的宽度决定了页目录和页表索引的宽度。 实验要求: 使用Windows 2000/XP 的API 函数,编写一个包含两个线程的进程,一个线程用于模拟内存分配活动,一个线程用于跟踪第一个线程的内存行为,而且要求两个线程之间通过信号量实现同步。模拟内存活动的线程可以从一个文件中读出要进行的内存操作,每个内存操作包括如下内容: 时间:操作等待时间。 块数:分配内存的粒度。 操作:包括保留(reserve)一个区域、提交(commit)一个区域、释放(release)一个区域、回收(decommit)一个区域和加锁(lock)与解锁(unlock)一个区域,可以将这些操作编号存放于文件。保留是指保留进程的虚拟地址空间,而不分配物理 存储空间。提交在内存中分配物理存储空间。回收是指释放物理内存空间,但在虚拟地址空间仍然保留,它与提交相对应,即可以回收已经提交的内存块。释放是指将物理存储和虚拟地址空间全部释放,它与保留(reserve)相对应,即可以释放已经保留的内存块。 大小:块的大小。 访问权限:共五种,分别为PAGE_READONLY,PAGE_READWRITE ,PAGE_EXECUTE,PAGE_EXECUTE_READ 和PAGE EXETUTE_READWRITE。可以将这些权限编号存放于文件中跟踪线程将页面大小、已使用的地址范围、物理内存总量,以及虚拟内存总量等信息显示出来。

实验操作系统存储管理实验报告

实验四操作系统存储管理实验报告 一、实验目的 存储管理的主要功能之一是合理地分配空间。请求页式管理是一种常用的虚拟存储管理技术。 本实验的目的是通过请求页式管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。 二、实验内容 (1)通过计算不同算法的命中率比较算法的优劣。同时也考虑了用户内存容量对命中率的影响。 页面失效次数为每次访问相应指令时,该指令所对应的页不在内存中的次数。 在本实验中,假定页面大小为1k,用户虚存容量为32k,用户内存容量为4页到32页。 (2)produce_addstream通过随机数产生一个指令序列,共320条指令。 A、指令的地址按下述原则生成: 1)50%的指令是顺序执行的 2)25%的指令是均匀分布在前地址部分 3)25%的指令是均匀分布在后地址部分 B、具体的实施方法是: 1)在[0,319]的指令地址之间随机选取一起点m; 2)顺序执行一条指令,即执行地址为m+1的指令; 3)在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m’; 4)顺序执行一条指令,地址为m’+1的指令 5)在后地址[m’+2,319]中随机选取一条指令并执行; 6)重复上述步骤1)~5),直到执行320次指令 C、将指令序列变换称为页地址流

在用户虚存中,按每k存放10条指令排列虚存地址,即320条指令在虚存中 的存放方式为: 第0条~第9条指令为第0页<对应虚存地址为[0,9]); 第10条~第19条指令为第1页<对应虚存地址为[10,19]); 。。。。。。 第310条~第319条指令为第31页<对应虚存地址为[310,319]); 按以上方式,用户指令可组成32页。 (3)计算并输出下属算法在不同内存容量下的命中率。 1)先进先出的算法

操作系统实验内存分配

精心整理西安邮电大学 (计算机学院) 课内实验报告 1. (1 (2 (3 原因,写出实验报告。 2.实验要求: 1)掌握内存分配FF,BF,WF策略及实现的思路; 2)掌握内存回收过程及实现思路; 3)参考本程序思路,实现内存的申请、释放的管理程序,调试运行,总结程序设计中出现的问题并找出原因,写出实验报告。

3.实验过程: 创建进程: 删除其中几个进程:(默认以ff首次适应算法方式排列) Bf最佳适应算法排列方式: wf最差匹配算法排列方式: 4.实验心得: 明 实验中没有用到循环首次适应算法,但是对其他三种的描述还是很详细,总的来说,从实验中还是学到了很多。 5.程序源代码: #include #include #include #include

#define PROCESS_NAME_LEN 32 //进程名长度 #define MIN_SLICE 10 //最小碎片的大小#define DEFAULT_MEM_SIZE 1024 //内存大小 #define DEFAULT_MEM_START 0 //起始位置 /*内存分配算法*/ #define MA_FF 1 #define MA_BF 2 #define MA_WF 3 /*描述每一个空闲块的数据结构*/ struct free_block_type { }; /* /* { }; /* /* void display_menu(); int set_mem_size(); void set_algorithm(); void rearrange(int algorithm); int rearrange_WF(); int rearrange_BF(); int rearrange_FF(); int new_process(); int allocate_mem(struct allocated_block *ab);

操作系统内存管理原理

内存分段和请求式分页 在深入i386架构的技术细节之前,让我们先返回1978年,那一年Intel 发布了PC处理器之母:8086。我想将讨论限制到这个有重大意义的里程碑上。如果你打算知道更多,阅读Robert L.的80486程序员参考(Hummel 1992)将是一个很棒的开始。现在看来这有些过时了,因为它没有涵盖Pentium处理器家族的新特性;不过,该参考手册中仍保留了大量i386架构的基本信息。尽管8086能够访问1MB RAM的地址空间,但应用程序还是无法“看到”整个的物理地址空间,这是因为CPU寄存器的地址仅有16位。这就意味着应用程序可访问的连续线性地址空间仅有64KB,但是通过16位段寄存器的帮助,这个64KB大小的内存窗口就可以在整个物理空间中上下移动,64KB逻辑空间中的线性地址作为偏移量和基地址(由16位的段寄存器给处)相加,从而构成有效的20位地址。这种古老的内存模型仍然被最新的Pentium CPU支持,它被称为:实地址模式,通常叫做:实模式。 80286 CPU引入了另一种模式,称为:受保护的虚拟地址模式,或者简单的称之为:保护模式。该模式提供的内存模型中使用的物理地址不再是简单的将线性地址和段基址相加。为了保持与8086和80186的向后兼容,80286仍然使用段寄存器,但是在切换到保护模式后,它们将不再包含物理段的地址。替代的是,它们提供了一个选择器(selector),该选择器由一个描述符表的索引构成。描述符表中的每一项都定义了一个24位的物理基址,允许访问16MB RAM,在当时这是一个很不可思议的数量。不过,80286仍然是16位CPU,因此线性地址空间仍然被限制在64KB。 1985年的80386 CPU突破了这一限制。该芯片最终砍断了16位寻址的锁链,将线性地址空间推到了4GB,并在引入32位线性地址的同时保留了基本的选择器/描述符架构。幸运的是,80286的描述符结构中还有一些剩余的位可以拿来使用。从16位迁移到32位地址后,CPU的数据寄存器的大小也相应的增加了两倍,并同时增加了一个新的强大的寻址模型。真正的32位的数据和地址为程序员带了实际的便利。事实上,在微软的Windows平台真正完全支持32位模型是在好几年之后。Windows NT的第一个版本在1993年7月26日发布,实现了真正意义上的Win32 API。但是Windows 3.x程序员仍然要处理由独立的代码和数据段构成的64KB内存片,Windows NT提供了平坦的4GB地址空间,在那儿可以使用简单的32位指针来寻址所有的代码和数据,而不需要分段。在内部,当然,分段仍然在起作用,就像我在前面提及的那样。不过管理段的所有责任都被移给了操作系统。

操作系统-进程管理实验报告

实验一进程管理 1.实验目的: (1)加深对进程概念的理解,明确进程和程序的区别; (2)进一步认识并发执行的实质; (3)分析进程争用资源的现象,学习解决进程互斥的方法; (4)了解Linux系统中进程通信的基本原理。 2.实验预备内容 (1)阅读Linux的sched.h源码文件,加深对进程管理概念的理解; (2)阅读Linux的fork()源码文件,分析进程的创建过程。 3.实验内容 (1)进程的创建: 编写一段程序,使用系统调用fork() 创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”,子进程分别显示字符“b”和“c”。试观察记录屏幕上的显示结果,并分析原因。 源代码如下: #include #include #include #include #include int main(int argc,char* argv[]) { pid_t pid1,pid2; pid1 = fork(); if(pid1<0){ fprintf(stderr,"childprocess1 failed"); exit(-1); } else if(pid1 == 0){ printf("b\n"); } 1/11

else{ pid2 = fork(); if(pid2<0){ fprintf(stderr,"childprocess1 failed"); exit(-1); } else if(pid2 == 0){ printf("c\n"); } else{ printf("a\n"); sleep(2); exit(0); } } return 0; } 结果如下: 分析原因: pid=fork(); 操作系统创建一个新的进程(子进程),并且在进程表中相应为它建立一个新的表项。新进程和原有进程的可执行程序是同一个程序;上下文和数据,绝大部分就是原进程(父进程)的拷贝,但它们是两个相互独立的进程!因此,这三个进程哪个先执行,哪个后执行,完全取决于操作系统的调度,没有固定的顺序。 (2)进程的控制 修改已经编写的程序,将每个进程输出一个字符改为每个进程输出一句话,再观察程序执行时屏幕上出现的现象,并分析原因。 将父进程的输出改为father process completed 2/11

实验4内存管理资料讲解

实验 4 内存管理

实验4内存管理 学校:FJUT 学号:3131903229 班级:计算机1302姓名:姜峰 注:其中LFU和NRU算法运行结果可能与其他人不同,只是实现方式不同,基本思路符合就可以。 .实验学时与类型 学时:2,课外学时:自定 实验类型:设计性实验二.实验目的 模拟实现请求页式存储管理中常用页面置换算法,理会操作系统对内存的 调度管理。 三?实验内容 要求:各算法要给出详细流程图以及执行结果截图。 假设有一程序某次运行访问的页面依次是: 0,124,3,4,5,1,2,5,1,2,3,4,5,6 ,请给出采用下列各页面置换算法时页面的换进换出情况,并计算各调度算法的命中率(命中率二非缺页次数/总访问次数),初始物理内存为空,物理内存可在4?20页中选择。 (1)FIFO :最先进入的页被淘汰; (2)LRU :最近最少使用的页被淘汰; (3)OPT :最不常用的页被淘汰;(选做) ⑷LFU :访问次数最少的页被淘汰(LFU)。(选做)

源代码: #i nclude #include #in elude #i nclude #defi ne MAXNUM 100 struct Phy_Memory{ //定义一个物理内存结构体 char Page; int time; }; char *OutPut; struct Phy_Memory *Phy_Page; void Print(char *PageStr,int Phy_PageNum,int absence){ // 打印图解函数int i,j; for(i=0;iPage!=*Temp;i++); if(i

操作系统 内存管理实验报告

同组同学学号: 同组同学姓名: 实验日期:交报告日期: 实验(No. 4 )题目:编程与调试:内存管理 实验目的及要求: 实验目的: 操作系统的发展使得系统完成了大部分的内存管理工作,对于程序员而言,这些内存管理的过程是完全透明不可见的。因此,程序员开发时从不关心系统如何为自己分配内存,而且永远认为系统可以分配给程序所需的内存。在程序开发时,程序员真正需要做的就是:申请内存、使用内存、释放内存。其它一概无需过问。本章的3个实验程序帮助同学们更好地理解从程序员的角度应如何使用内存。 实验要求: 练习一:用vim编辑创建下列文件,用GCC编译工具,生成可调试的可执行文件,记录并分析执行结果,分析遇到的问题和解决方法。 练习二:用vim编辑创建下列文件,用GCC编译工具,生成可调试的可执行文件,记录并分析执行结果。 练习三:用vim编辑创建下列文件,用GCC编译工具,生成可调试的可执行文件,记录并分析执行结果。 改编实验中的程序,并运行出结果。 实验设备:多媒体电脑 实验内容以及步骤: 在虚拟机中编写好以下程序: #include #include #include int main(void) { char *str; /* 为字符串申请分配一块内存*/ if ((str = (char *) malloc(10)) == NULL) { printf("Not enough memory to allocate buffer\n"); return(1); /* 若失败则结束程序*/ } /* 拷贝字符串“Hello”到已分配的内存空间*/ strcpy(str, "Hello"); /* 显示该字符串*/ printf("String is %s\n", str); /* 内存使用完毕,释放它*/ free(str); return 0; } 调试过后得出的结果截图如下:(由图可看出我将此程序以aa.c为文件名保存,调试后出现aa1文件,调试结果出现语句“String is Hello”)

操作系统实验二

操作系统实验实验二进程管理 学号 1215108019 姓名克帆 学院信息学院 班级 12电子2

实验目的 1、理解进程的概念,明确进程和程序的区别。 2、理解并发执行的实质。 3、掌握进程的创建、睡眠、撤销等进程控制方法。 实验容与要求 基本要求:用C语言编写程序,模拟实现创建新的进程;查看运行进程;换出某个进程;杀死进程等功能。 实验报告容 1、进程、进程控制块等的基本原理。 进程是现代操作系统中的一个最基本也是最重要的概念,掌握这个概念对于理解操作系统实质,分析、设计操作系统都有其非常重要的意义。为了强调进程的并发性和动态性,可以给进程作如下定义:进程是可并发执行的程序在一个数据集合上的运行过程,是系统进行资源分配和调度的一个独立单位。 进程又就绪、执行、阻塞三种基本状态,三者的变迁图如下: 由于多个程序并发执行,各程序需要轮流使用CPU,当某程序不在CPU上运行时,必须保留其被中断的程序的现场,包括:断点地址、程序状态字、通用寄存器的容、堆栈容、程序当前状态、程序的大小、运行时间等信息,以便程序再次获得CPU时,能够正确执行。为了保存这些容,需要建立—个专用数据结构,我们称这个数据结构为进程控制块PCB (Process Control Block)。 进程控制块是进程存在的惟一标志,它跟踪程序执行的情况,表明了进程在当前时刻的状态以及与其它进程和资源的关系。当创建一个进程时,实际上就是为其建立一个进程控制块。 在通常的操作系统中,PCB应包含如下一些信息: ①进程标识信息。为了标识系统中的各个进程,每个进程必须有惟一的标识名或标 识数。 ②位置信息。指出进程的程序和数据部分在存或外存中的物理位置。 ③状态信息。指出进程当前所处的状态,作为进程调度、分配CPU的依据。 ④进程的优先级。一般根据进程的轻重缓急其它信息。 这里给出的只是一般操作系统中PCB所应具有的容,不同操作系统的PCB结构是不同的,我们将在2.8节介绍Linux系统的PCB结构。

操作系统实验报告--内存管理

操作系统课程设计 实验报告 学院:信息学院 班级:计1109班 姓名:林海慧 学号:XXXXXXXXXXXXX 指导老师:XXXX

实验三、内存管理 一、[问题描述] 设计一个请求页式存储管理方案,为简单起见。页面淘汰算法采用FIFO页面淘汰算法,并且在淘汰一页时,只将该页在页表中修改状态位。而不再判断它是否被改写过,也不将它写回到辅存。 二、[基本要求] 页面尺寸1K,输入进程大小(例如5300bytes),对页表进行初始化, 页表结构: ,块号分别为0、1、2,页框管理表(空闲块表): 任意输入一个需要访问的指令地址流(例如:3635、3642、1140、0087、1700、5200、4355,输入负数结束),打印页表情况。 每访问一个地址时,首先要计算该地址所在的页的页号,然后查页表,判断该页是否在主存——如果该页已在主存,则打印页表情况;如果该页不在主存且页框未满,则调入该页并修改页表,打印页表情况;如果该页不在主存且页框已满,则按FIFO页面淘汰算法淘汰一页后调入所需的页,修改页表,打印页表情况; 存储管理算法的流程图如下:

三、源代码 #include #include #define BUSY 1 #define NOTBUSY 0 struct PageB{ int PNumber; //页号

int BNumber; //物理块号 int Count; //计数器,在内存驻留时间 bool State; //状态位 } ; PageB Page[6]={{0,-1,0,false},{1,-1,0,false},{2,-1,0,false},{3,-1,0,false},{4,-1,0,false},{5,-1,0,false}}; int queye=0; struct Physical{ int BNumber; //物理块号 int State; //状态位 }Physical[3]={{0,0},{1,0},{2,0}}; int MaxSzie, MaxCount = 0; bool IsInPage(int P)//判断是否在内存 { int i=0; int flag=0; for (i = 0; i <= 5; i++) { if (Page[i].PNumber == P && Page[i].State == true) { printf("\n页在主存,打印页表:"); printf("\n页号:%d 物理块号:%d 状态:%d(true)",Page[i].PNumber,Page[i].BNumber,Page[i].State); flag=1; } } if(flag==1) return true; else return false; } void FIFO(int P)//FIFO页面置换算法 { int i, j, k; int BNumber;//暂存物理块号 for(i = 0; i <= 5; i++) { if (Page[i].PNumber == P && Page[i].State == false) { printf("页号%d在辅存\n",P); //分配给该进程的物理块均被占

相关主题
文本预览
相关文档 最新文档