河北工业大学操作系统实验报告linux - 和windows部分 联系客服

发布时间 : 星期二 文章河北工业大学操作系统实验报告linux - 和windows部分更新完毕开始阅读53c39916a8956bec0975e38a

软件c122郭嵘峥 125448

分页文件的大小。

“任务管理器”的“认可用量”区域显示的信息还说明了系统的主内存是否足以满足系统执行的任务。如果认可“总数”值经常超过系统中的内存数量,那么系统的物理内存可能不足。

3.2 Windows 2000内存结构

(实验估计时间:120分钟)

? ? ? ?

背景知识 实验目的

工具/准备工作 实验内容与步骤

背景知识

Windows 2000是32位的操作系统,它使计算机CPU可以用32位地址对32位内存块进行操作。内存中的每一个字节都可以用一个32位的指针来寻址。这样,最大的存储空间就是232字节或4000兆字节 (4GB) 。这样,在Windows下运行的每一个应用程序都认为能独占可能的4GB大小的空间。

而另一方面,实际上没有几台机器的RAM能达到4GB,更不必说让每个进程都独享4GB内存了。Windows在幕后将虚拟内存 (virtual memory,VM) 地址映射到了各进程的物理内存地址上。而所谓物理内存是指计算机的RAM和由Windows分配到用户驱动器根目录上的换页文件。物理内存完全由系统管理。 实验目的

1) 通过实验了解Windows 2000内存的使用,学习如何在应用程序中管理内存,体会Windows应用程序内存的简单性和自我防护能力。

2) 了解Windows 2000的内存结构和虚拟内存的管理,进而了解进程堆和Windows为使用内存而提供的一些扩展功能。 工具/准备工作

在开始本实验之前,请回顾教科书的相关内容。 您需要做以下准备:

1) 一台运行Windows 2000 Professional操作系统的计算机。 2) 计算机中需安装Visual C++ 6.0专业版或企业版。 实验内容与步骤

Windows提供了一个API即GetSystemInfo() ,以便用户能检查系统中虚拟内存的一些特性。清单5-1显示了如何调用该函数以及显示系统中当前内存的参数。

步骤1:登录进入Windows 2000 Professional。

步骤2:在“开始”菜单中单击“程序-Microsoft Visual Studio 6.0 – Microsoft Visual C++ 6.0”命令,进入Visual C++窗口。

软件c122郭嵘峥 125448

步骤3:在工具栏单击“打开”按钮,在“打开”对话框中找到并打开实验源程序5-1.cpp。

清单5-1 获取有关系统的内存设置的信息 // 工程vmeminfo

# include # include # include #i nclude

# pragma comment(lib, “shlwapi.lib”)

void main() {

// 首先获得系统信息 SYSTEM_INFO si;

:: ZeroMemory(&si, sizeof(si) ) ; :: GetSystemInfo(&si) ;

// 使用外壳辅助程序对一些尺寸进行格式化 TCHAR szPageSize [MAX_PATH] ;

:: StrFormatByteSize(si.dwPageSize, szPageSize, MAX_PATH) ;

DWORD dwMemSize = (DWORD) si.lpMaximumApplicationAddress - (DWORD) si.lpMinimumApplicationAddress; TCHAR szMemSize [MAX_PATH] ;

:: StrFormatByteSize(dwMemSize, szMemSize, MAX_PATH) ;

// 将内存信息显示出来

std :: cout << “Virtual memory page size: ” << szPageSize << std :: endl;

std :: cout.fill (?0?) ;

std :: cout << “Minimum application address: 0x” << std :: hex << std :: setw(8)

<< (DWORD) si.lpMinimumApplicationAddress << std :: endl;

std :: cout << “Maximum application address: 0x” << std :: hex << std :: setw(8)

<< (DWORD) si.lpMaximumApplicationAddress << std :: endl;

std :: cout << “Total available virtual memory: ” << szMemSize << std :: endl ; }

步骤4:单击“Build”菜单中的“Compile 5-1.cpp”命令,并单击“是”按钮确认。系统对5-1.cpp进行编译。

步骤5:编译完成后,单击“Build”菜单中的“Build 5-1.exe”命令,建立5-1.exe可执行文件。

操作能否正常进行?如果不行,则可能的原因是什么? 可以正常运行

步骤6:在工具栏单击“Execute Program” (执行程序) 按钮,执行5-1.exe程序。 运行结果 (如果运行不成功,则可能的原因是什么?) :

1) 虚拟内存每页容量为: 4.00KB 2) 最小应用地址: 0x00010000 3) 最大应用地址: 0x7ffeffff 4) 当前可供应用程序使用的内存空间为: 1.99GB 5) 当前计算机的实际内存大小为: 512MB 阅读和分析程序5-1,请回答问题:

1) 理论上每个Windows应用程序可以独占的最大存储空间是: 4GB 2) 在清单5-1程序中,用于检查系统中虚拟内存特性的API函数是: GetSystemInfo(&si)

软件c122郭嵘峥 125448

提示:可供应用程序使用的内存空间实际上已经减去了开头与结尾两个64KB的保护区。虚拟内存空间中的64KB保护区是防止编程错误的一种Windows方式。任何对内存中这一区域的访问 (读、写、执行) 都将引发一个错误陷井,从而导致错误并终止程序的执行。也就是说,假如用户有一个NULL指针 (地址为0) ,但仍试图在此之前很近的地址处使用另一个指针,这将因为试图从更低的保留区域读写数据,从而产生意外错误并终止程序的执行。

3.3 Windows 2000进程的“一生”

(实验估计时间:120分钟)

? ? ? ?

? 背景知识 ? 实验目的

? 工具/准备工作 ? 实验内容与步骤

背景知识

1. 创建进程

2. 正在运行的进程 3. 终止进程

Windows所创建的每个进程都从调用CreateProcess() API函数开始,该函数的任务是在对象管理器子系统内初始化进程对象。每一进程都以调用ExitProcess() 或TerminateProcess() API函数终止。通常应用程序的框架负责调用 ExitProcess() 函数。对于C++ 运行库来说,这一调用发生在应用程序的main() 函数返回之后。

1. 创建进程

CreateProcess() 调用的核心参数是可执行文件运行时的文件名及其命令行。表 3-4详细地列出了每个参数的类型和名称。

表3-4 CreateProcess() 函数的参数 参数名称 LPCTSTR lpApplivationName LPCTSTR lpCommandLine LPSECURIITY_ATTRIBUTES lpProcessAttributes LPSECURIITY_ATTRIBUTES lpThreadAttributes BOOL bInheritHandle DWORD dwCreationFlage LPVOID lpEnvironment 使用目的 全部或部分地指明包括可执行代码的EXE文件的文件名 向可执行文件发送的参数 返回进程句柄的安全属性。主要指明这一句柄是否应该由其他子进程所继承 返回进程的主线程的句柄的安全属性 一种标志,告诉系统允许新进程继承创建者进程的句柄 特殊的创建标志 (如CREATE_SUSPENDED) 的位标记 向新进程发送的一套环境变量;如为null值则发送调用者环境 软件c122郭嵘峥 125448

LPCTSTR lpCurrentDirectory STARTUPINFO lpStartupInfo LPPROCESS_INFORMATION lpProcessInformation 新进程的启动目录 STARTUPINFO结构,包括新进程的输入和输出配置的详情 调用的结果块;发送新应用程序的进程和主线程的句柄和ID

可以指定第一个参数,即应用程序的名称,其中包括相对于当前进程的当前目录的全路径或者利用搜索方法找到的路径;lpCommandLine参数允许调用者向新应用程序发送数据;接下来的三个参数与进程和它的主线程以及返回的指向该对象的句柄的安全性有关。

然后是标志参数,用以在dwCreationFlags参数中指明系统应该给予新进程什么行为。经常使用的标志是CREATE_SUSPNDED,告诉主线程立刻暂停。当准备好时,应该使用ResumeThread() API来启动进程。另一个常用的标志是CREATE_NEW_CONSOLE,告诉新进程启动自己的控制台窗口,而不是利用父窗口。这一参数还允许设置进程的优先级,用以向系统指明,相对于系统中所有其他的活动进程来说,给此进程多少CPU时间。

接着是CreateProcess() 函数调用所需要的三个通常使用缺省值的参数。第一个参数是lpEnvironment参数,指明为新进程提供的环境;第二个参数是lpCurrentDirectory,可用于向主创进程发送与缺省目录不同的新进程使用的特殊的当前目录;第三个参数是STARTUPINFO数据结构所必需的,用于在必要时指明新应用程序的主窗口的外观。

CreateProcess() 的最后一个参数是用于新进程对象及其主线程的句柄和ID的返回值缓冲区。以PROCESS_INFORMATION结构中返回的句柄调用CloseHandle() API函数是重要的,因为如果不将这些句柄关闭的话,有可能危及主创进程终止之前的任何未释放的资源。

2. 正在运行的进程

如果一个进程拥有至少一个执行线程,则为正在系统中运行的进程。通常,这种进程使用主线程来指示它的存在。当主线程结束时,调用ExitProcess() API函数,通知系统终止它所拥有的所有正在运行、准备运行或正在挂起的其他线程。当进程正在运行时,可以查看它的许多特性,其中少数特性也允许加以修改。

首先可查看的进程特性是系统进程标识符 (PID) ,可利用GetCurrentProcessId() API函数来查看,与GetCurrentProcess() 相似,对该函数的调用不能失败,但返回的PID在整个系统中都可使用。其他的可显示当前进程信息的API函数还有GetStartupInfo()和GetProcessShutdownParameters() ,可给出进程存活期内的配置详情。

通常,一个进程需要它的运行期环境的信息。例如API函数GetModuleFileName() 和GetCommandLine() ,可以给出用在CreateProcess() 中的参数以启动应用程序。在创建应用程序时可使用的另一个API函数是IsDebuggerPresent() 。

可利用API函数GetGuiResources() 来查看进程的GUI资源。此函数既可返回指定进程中的打开的GUI对象的数目,也可返回指定进程中打开的USER对象的数目。进程的其他性能信息可通过GetProcessIoCounters()、GetProcessPriorityBoost() 、GetProcessTimes() 和GetProcessWorkingSetSize() API得到。以上这几个API函数都只需要具有PROCESS_QUERY_INFORMATION访问权限的指向所感兴趣进程的句柄。

另一个可用于进程信息查询的API函数是GetProcessVersion() 。此函数只需感兴趣进程的PID (进程标识号) 。本实验程序清单3-6中列出了这一API函数与GetVersionEx() 的共同作用,可确定运行进程的系统的版本号。

3. 终止进程

所有进程都是以调用ExitProcess() 或者TerminateProcess() 函数结束的。但最好使用前者而不要使用后者,因为进程是在完成了它的所有的关闭“职责”之后以正常的终止方式来