版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
本文格式為Word版,下載可任意編輯——操作系統(tǒng)試驗指導書2023春季學期
操作系統(tǒng)試驗指導書
計算機科學與軟件學院
2023年
試驗一進程控制與描述
一、試驗目的
通過對WindowsXP編程,進一步熟悉操作系統(tǒng)的基本概念,較好地理解WindowsXP的結(jié)構(gòu)。通過創(chuàng)立進程、觀測正在運行的進程和終止進程的程序設計和調(diào)試操作,進一步熟悉操作系統(tǒng)的進程概念,理解WindowsXP進程的“一生〞。
二、試驗環(huán)境
硬件環(huán)境:計算機一臺,局域網(wǎng)環(huán)境;
軟件環(huán)境:WindowsXP,VisualC++6.0專業(yè)版或企業(yè)版。三、試驗內(nèi)容和步驟
第一部分Windows編程
WindowsXP可以識別的程序包括控制臺應用程序、GUI應用程序和服務應用程序。本試驗中主要用到的是控制臺應用程序和GUI應用程序。
1、簡單的控制臺應用程序
創(chuàng)立一個名為“Hello〞的應用程序,在“開始〞菜單中單擊“程序〞-“附件〞-“記事本〞命令,將程序鍵入記事本中,并把代碼保存為1-1.cpp。
程序1-1WindowsXP的GUI應用程序#includevoidmain(){
Std::coutCL1-1.cpp
運行1-1.EXE程序,運行結(jié)果是:(假使運行不成功,則可能的原因是什么?)
________________________________________________________________________________________________________________________________________2、GUI應用程序
WindowsXPProfessional下的GUI應用程序,使用VisualC++編譯器創(chuàng)立一個GUI應用程序,代碼中包括了WinMain()方法,該方法GUI類型的應用程序的標準入口點。
在“開始〞菜單中單擊“程序〞-“附件〞-“記事本〞命令,將程序鍵入記事本中,并把代碼保存為1-2.cpp。
程序1-2WindowsXP的GUI應用程序//msgbox項目
#include//標準的include//告訴連接器與包括MessageBoxAPI函數(shù)的user32庫進行連接#pragmacomment(lib,“user32.lib〞)
//這是一個可以彈出信息框然后退出的筒單的應用程序intAPIENTRYWinMain(HINSTANCE/*hInstance*/,HINSTANCE/*hPrevInstance*/,LPSTR/*lpCmdLine*/,int/*nCmdShow*/){
::MessageBox(NULL,//沒有父窗口“Hello,Windows2000〞,//消息框中的文本“Greetings〞,//消息框標題MB_OK);//其中只有一個OK按鈕//返回0以便通知系統(tǒng)不進入消息循環(huán)return(0);
}
也可以利用任何其他文本編輯器鍵入程序代碼,假使這樣,例如使用WORD來鍵入和編輯程序,則應當注意什么問題?
________________________________________________________________________________________________________________________________________在“命令提醒符〞窗口運行CL.EXE,產(chǎn)生1-2.EXE文件:C:\\>CL1-2.cpp
在程序1-2的GUI應用程序中,首先需要Windows.h頭文件,以便獲得傳送給WinMain()和MessageBox()API函數(shù)的數(shù)據(jù)類型定義。
接著的pragma指令指示編譯器/連接器找到User32.LIB庫文件并將其與產(chǎn)生的EXE文件連接起來。這樣就可以運行簡單的命令行命令CLMsgBox.CPP來創(chuàng)立這一應用程序,假使沒有pragma指令,則MessageBox()API函數(shù)就成為未定義的了。這一指令是VisualStudioC++編譯器特有的。
接下來是WinMain()方法。其中有四個由實際的低級入口點傳遞來的參數(shù)。hInstance參數(shù)用來裝入與代碼相連的圖標或位圖一類的資源,無論何時,都可用GetModuleHandle()API函數(shù)將這些資源提取出來。系統(tǒng)利用實例句柄來指明代碼和初始的數(shù)據(jù)裝在內(nèi)存的何處。句柄的數(shù)值實際上是EXE文件映像的基地址,尋常為0x00400000。下一個參數(shù)hPrevInstance是為向后兼容而設的,現(xiàn)在系統(tǒng)將其設為NULL。應用程序的命令行(不包括程序的名稱)是lpCmdLine參數(shù)。另外,系統(tǒng)利用nCmdShow參數(shù)告訴應用程序如何顯示它的主窗口(選項包括最小化、最大化和正常)。
最終,程序調(diào)用MessageBox()API函數(shù)并退出。假使在進入消息循環(huán)之前就終止運行的話,最終必需返回0。
運行結(jié)果(試將其中的信息與程序1-1.EXE的運行結(jié)果進行比較):
_____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
3、進程對象
操作系統(tǒng)將當前運行的應用程序看作是進程對象。利用系統(tǒng)提供的惟一的稱為句柄(HANDLE)的號碼,就可與進程對象交互。這一號碼只對當前進程有效。
本試驗表示了一個簡單的進程句柄的應用。在系統(tǒng)中運行的任何進程都可調(diào)用GetCurrentProcess()API函數(shù),此函數(shù)可返回標識進程本身的句柄。然后就可在Windows需要該進程的有關(guān)狀況時,利用這一句柄來提供。
程序1-3:獲得和使用進程的句柄
//prochandle項目#include#include
//確定自己的優(yōu)先權(quán)的簡單應用程序voidmain(){
//從當前進程中提取句柄
HANDLEhProcessThis=::GetCurrentProcess();
//請求內(nèi)核提供該進程所屬的優(yōu)先權(quán)類
DWORDdwPriority=::GetPriorityClass(hProcessThis);
//發(fā)出消息,為用戶描述該類
std::cout〞;break;}
std::coutCL1-3.cpp
運行結(jié)果:__________________________________________________________________________________________________________________________________________________________________________________________________________
將程序1-4.cpp程序鍵入記事本中,并把代碼保存為1-4.cpp。程序1-4顯示如何找出系統(tǒng)中正在運行的所有進程,如何利用OpenProcess()API函數(shù)來獲得每一個訪問進程的進一步信息。
程序1-4利用句柄查出進程的詳細信息//proclist項目
#include#include#include
//當在用戶模式機內(nèi)核模式下都提供所耗時間時,在內(nèi)核模式下進行所耗時間的64位計算的幫助方法DWORDGetKernelModePercentage(constFILETIMEULONGLONGqwUser=
(((ULONGLONG)ftUser.dwHighDateTime)CL1-4.cpp
運行結(jié)果:__________________________________________________________________________________________________________________________________
l}else{
Parent();}
return0;}
程序說明白一個進程從“生〞到“死〞的整個一生。第一次執(zhí)行時,它創(chuàng)立一個子進程,其行為宛如“父親〞。在創(chuàng)立子進程之前,先創(chuàng)立一個互斥的內(nèi)核對象,其行為對于子進程來說,宛如一個“自殺彈〞。當創(chuàng)立子進程時,就開啟了互斥體并在其他線程中進行別的處理工作,同時等待著父進程使用ReleaseMutex()API發(fā)出“死亡〞信號。然后用Sleep()API調(diào)用來模擬父進程處理其他工作,等完成時,指令子進程終止。
當調(diào)用ExitProcess()時要防備,進程中的所有線程都被立刻通知中止。在設計應用程序時,必需讓主線程在正常的C++運行期關(guān)閉(這是由編譯器提供的缺省行為)之后來調(diào)用這一函數(shù)。當它轉(zhuǎn)向受信狀態(tài)時,尋常可創(chuàng)立一個每個活動線程都可等待和中止的終止事件。
在正常的終止操作中,進程的每個工作線程都要終止,由主線程調(diào)用ExitProcess()。接著,管理層對進程增加的所有對象釋放引用,并將用GetExitCodeProcess()建立的退出代碼從STILL_ACTIVE改變?yōu)樵贓xitProcess()調(diào)用中返回的值。最終,主線程對象也宛如進程對象一樣轉(zhuǎn)變?yōu)槭苄艩顟B(tài)。
等到所有開啟的句柄都關(guān)閉之后,管理層的對象管理器才銷毀進程對象本身。還沒有一種函數(shù)可取得終止后的進程對象為其參數(shù),從而使其“復活〞。當進程對象引用一個終止了的對象時,有好幾個API函數(shù)依舊是有用的。進程可使用退出代碼將終止方式通知給調(diào)用GetExitCodeProcess()的其他進程。同時,GetProcessTimes()API函數(shù)可向主調(diào)者顯示進程的終止時間。
運行結(jié)果:
1)__________________________________________________________________表示:______________________________________________________________2)__________________________________________________________________表示:______________________________________________________________
在熟悉源代碼的基礎上,利用本試驗介紹的API函數(shù)來嘗試改進本程序(例如使用GetProcessTimes()API函數(shù))并運行。請描述你所做的工作:
____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
四、試驗總結(jié)
請總結(jié)一下本次試驗的收獲、教訓和感受,結(jié)合課本內(nèi)容談一下你對進程的理解。
試驗二并發(fā)與調(diào)度
一、試驗目的
在本試驗中,通過對事件和互斥體對象的了解,來加深對WindowsXP線程同步的理解。通過分析試驗程序,了解管理事件對象的API。了解在進程中如何使用事件對象,在進程中如何使用互斥體對象,線程如何通過文件映射對象發(fā)送數(shù)據(jù)。
二、試驗環(huán)境
硬件環(huán)境:計算機一臺,局域網(wǎng)環(huán)境;
軟件環(huán)境:WindowsXPProfessional,VisualC++6.0專業(yè)版或企業(yè)版。三、試驗內(nèi)容和步驟第一部分:互斥體對象
本程序中顯示的類CCountUpDown使用了一個互斥體來保證對兩個線程間單一數(shù)值的訪問。每個線程都企圖獲得控制權(quán)來改變該數(shù)值,然后將該數(shù)值寫入輸出流中。創(chuàng)立者實際上創(chuàng)立的是互斥體對象,計數(shù)方法執(zhí)行等待并釋放,為的是共同使用互斥體所需的資源(因而也就是共享資源)。
1、利用互斥體保護共享資源
//mutex項目
#include#include
//利用互斥體來保護同時訪問的共享資源classCCountUpDown{
public:
//創(chuàng)立者創(chuàng)立兩個線程來訪問共享值CCountUpDown(intnAccesses):m_hThreadlnc(INVALID_HANDLE_VALUE),m_hThreadDec(INVALID_HANDLE_VALUE),m_hMutexValue(INVALID_HANDLE_VALUE),m_nValue(0),
m_nAccess(nAccesses){
//創(chuàng)立互斥體用于訪問數(shù)值m_hMutexValue=::CreateMutex(NULL,//缺省的安全性TRUE,//初始時擁有,在所有的初始化終止時將釋放NULL);//匿名的m_hThreadInc=::CreateThread(NULL,//缺省的安全性0,//缺省堆棧IncThreadProc,//類線程進程reinterpret_cast(this),//線程參數(shù)0,//無特別的標志NULL);//忽略返回的idm_hThreadDec=::CreateThread(NULL,//缺省的安全性0,//缺省堆棧DecThreadProc,//類線程進程reinterpret_cast(this),//線程參數(shù)0,//無特別的標志NULL);//忽略返回的id//允許另一線程獲得互斥體
::ReleaseMutex(m_hMutexValue);}
//解除程序釋放對對象的引用
virtual~CCountUpDown()
{
::CloseHandle(m_hThreadInc);::CloseHandle(m_hThreadDec);::CloseHandle(m_hMutexValue);}
//簡單的等待方法,在兩個線程終止之前可暫停主調(diào)者virtualvoidWaitForCompletion(){
//確保所有對象都已準備好if(m_hThreadInc!=INVALID_HANDLE_VALUE::WaitForSingleObject(m_hThreadDec,INFINITE);}}
protected:
//改變共享資源的簡單的方法virtualvoidDoCount(intnStep){
//循環(huán),直到所有的訪問都終止為止while(m_nAccess>0){
//等待訪問數(shù)值
::WaitForSingleObject(m_hMutexValue,INFINITE);//改變并顯示該值m_nValue+=nStep;
std::cout(lpParam);
//調(diào)用對象的增加方法并返回一個值
pThis->DoCount(+1);return(0);}
staticDWORDWINAPIDecThreadProc(LPVOIDlpParam){
//將參數(shù)解釋為?this?指針CCountUpDown*pThis=
reinterpret_cast(lpParam);//調(diào)用對象的減少方法并返回一個值pThis->DOCount(-1);return(0);}
protected:
HANDLEm_hThreadInc;HANDLEm_hThreadDec;HANDLEm_hMutexValue;intm_nValue;intm_nAccess;
};
voidmain()
{
CCountUpDownud(50);ud.WaitForCompletion();}
分析程序的運行結(jié)果,可以看到線程(加和減線程)的交替執(zhí)行(由于Sleep()API允許Windows切換線程)。在每次運行之后,數(shù)值應當返回初始值(0),由于在每次運行之后寫入線程在等待隊列中變成最終一個,內(nèi)核保證它在其他線程工作時不會再運行。
1)請描述運行結(jié)果(假使運行不成功,則可能的原因是什么?):
____________________________________________________________________________________________________________________________________________2)根據(jù)運行輸出結(jié)果,對照分析程序,可以看出程序運行的流程嗎?請簡單描述:____________________________________________________________________________________________________________________________________________
其次部分線程通過文件對象發(fā)送數(shù)據(jù)
WindowsXP提供的線程間通訊類內(nèi)核對象允許同一進程或跨進程的線程之間相互發(fā)送信息,包括文件、文件映射、郵件位和命名管道等,其中最常用的是文件和文件映射。這類對象允許一個線程很簡單地向同一進程或其他進程中的另一線程發(fā)送信息。
1、演示線程通過文件對象發(fā)送數(shù)據(jù)
下邊程序代碼展示了線程如何通過文件對象在永久存儲介質(zhì)上相互發(fā)送數(shù)據(jù)。程序只是激活并啟動了一個線程接著一個線程的創(chuàng)立線程。每個線程從指定的文件中讀取數(shù)據(jù),并對數(shù)據(jù)進行修改,其修改增量是以創(chuàng)立時發(fā)送給它的數(shù)量進行的,然后將新數(shù)值寫回文件。
#inc1ude#include//要使用的文件名
staticLPCTSTRg_szFileName=“w2kdg.Fileobj.file.data.txt〞;
//在數(shù)據(jù)文件中讀取當前數(shù)據(jù)的簡單線程時將傳遞來的該數(shù)據(jù)增加,并寫回數(shù)據(jù)文件中staticDWORDWINAPIThreadProc(LPVOIDlpParam){
//將參數(shù)翻譯為長整數(shù)
LONGnAdd=reinterpret_cast(lpParam);//建立完全的指定文件名(包括路徑信息)TCHARszFullName[MAX_PATH];
::GetTempPath(MAX_PATH,szFullName);//取得路徑::strcat(szFullName,g_szFileName);//開啟文件對象
HANDLEhFile=::CreateFile(szFullName,//文件的完全名稱GENERIC-READ|GENERIC_WRITE,//具有所有的訪問權(quán)FILE_SHARE_READ,//允許其他線程讀取NULL,//缺省的安全性OPEN_ALWAYS,//創(chuàng)立或開啟文件FILE_ATTRIBUTE_NORMAL,//普通文件NULL);//無模板文件if(hFile!=INVALID_HANDLE_VALUE){
//讀取當前數(shù)據(jù)LONGnValue(0);DWORDdwXfer(0);::ReadFile(hFile,//要讀取的文件reinterpret_cast(//無重疊I/O
if(dwXfer==sizeof(nValue))
{std::cout(//無重疊I/O
if(dwXfer==sizeof(nValue))
{std::cout0;--nTotal)
{
//啟動線程
HANDLEhThread=::CreateThread(
NULL,//缺省的安全性0,//缺省的堆棧ThreadProc,//線程函數(shù)reinterpret_cast(1),//增量0,//無特別的創(chuàng)立標志
NULL);//忽略線程id//等待線程完成
::WaitForSingleObject(hThread,INFINITE);
::Sleep(500);//放慢顯示速度,便利觀測//釋放指向線程的句柄::CloseHandle(hThread);hThread=INVALID_HANDLE_VALUE;
}}
運行結(jié)果(假使運行不成功,則可能的原因是什么?):
____________________________________________________________________________________________________________________________________________閱讀和分析程序,請回復問題:
1)程序中啟動了多少個單獨的讀寫線程?
____________________________________________________________________2)使用了哪個系統(tǒng)API函數(shù)來創(chuàng)立線程例程?
____________________________________________________________________3)文件的讀和寫操作分別使用了哪個API函數(shù)?
____________________________________________________________________________________________________________________________________________
每次運行進程時,都可看到程序中的每個線程從前面的線程中讀取數(shù)據(jù)并將數(shù)據(jù)增加,文件中的數(shù)值連續(xù)增加。這個例如是很簡單的通訊機制??蓪⑦@一例如用作編寫自己的文件讀/寫代碼的模板。
請注意程序中寫入之前文件指針的重置。重置文件指針是必要的,由于該指針在讀取終止時將處于前四個字節(jié)之后,同一指針還要用于向文件寫入數(shù)據(jù)。假使函數(shù)向該處寫入新數(shù)值,則下次進程運行時,只能讀到原來的數(shù)值。那么:
4)在程序中,重置文件指針使用了哪一個函數(shù)?
____________________________________________________________________5)從輸出結(jié)果,對照分析程序,可以看出程序運行的流程嗎?請簡單描述:
____________________________________________________________________________________________________________________________________________
2、演示使用映射文件的內(nèi)存交換數(shù)據(jù)的線程
#include#include//仲裁訪問的互斥體
staticHANDLEg_hMutexMapping=INVALID_HANDLE_VALUE;//增加共享內(nèi)存中的數(shù)值的簡單線程
staticDWORDWINAPIThreadProc(LPVOIDlpParam){
//將參數(shù)看作句柄
HANDLEhMapping=reinterpret_cast(IpParam);
//等待對文件的訪問
::WaitForSingleObject(g_hMutexMapping,INFINITE);//映射視圖
LPVOIDpFile=::MapViewOfFile(hMapping,//保存文件的對象FILE_MAP_ALL_ACCESS,//獲得讀寫權(quán)限0,//在文件的開頭處(高32位)開始0,//...(低32位)0);//映射整個文件if(pFile!=NULL){
//將數(shù)據(jù)看作長整數(shù)
LONG*pnData=reinterpret_cast(pFile);//改動數(shù)據(jù)++(*pnData);//顯示新數(shù)值
std::cout
if(pData!=NULL){::ZeroMemory(pData,sizeof(LONG));}
//關(guān)閉文件視圖
::UnmapViewOfFile(pData);}
return(hMapping);}
voidmain(){
//創(chuàng)立數(shù)據(jù)文件
HANDLEhMapping=::MakeSharedFile();//創(chuàng)立仲裁的互斥體
g_hMutexMapping=::CreateMutex(NULL,FALSE,NULL);//根據(jù)文件創(chuàng)立100個線程來讀寫
for(intnTotal=100;nTotal>0;--nTotal){
//啟動線程
HANDLEhThread=::CreateThread(NULL,//缺省的安全性0,//缺省堆棧ThreadProc,//線程函數(shù)reinterpret_cast(hMapping),//增量0,//無特別的創(chuàng)立標志NULL);//忽略線程id//等待最終的線程釋放if(nTotal==l){std::cout#include#include#include
#pragmacomment(lib,\
//以可讀方式對用戶顯示保護的輔助方法。
//保護標記表示允許應用程序?qū)?nèi)存進行訪問的類型//以及操作系統(tǒng)強制訪問的類型
inlineboolTestSet(DWORDdwTarget,DWORDdwMask){
return((dwTarget}
#defineSHOWMASK(dwTarget,type)\\if(TestSet(dwTarget,PAGE_##type))\\{std::cout0)//實際使用的緩沖區(qū)大小
{//除去路徑并顯示::PathStripPath(szFilename);std::coutCommitted,READWRITE,Private
可描述為:具有READWRITE權(quán)限的已調(diào)配私有內(nèi)存區(qū)。
將系統(tǒng)當前的自由區(qū)(free)虛擬地址空間填入表中。
地址大小虛擬地址空間類型freefreefreefreefree訪問權(quán)限描述
將系統(tǒng)當前的已調(diào)配區(qū)(committed)虛擬地址空間填入表中。地址大小虛擬地址空間類型committedcommittedcommittedcommittedcommitted訪問權(quán)限描述
將系統(tǒng)當前的保存區(qū)(reserved)虛擬地址空間填入表5-8中。地址大小虛擬地址空間類型reservedreservedreservedreservedreserved訪問權(quán)限描述
2)從上述輸出結(jié)果,對照分析程序,請簡單描述程序運行的流程:
____________________________________________________________________________________________________________________________________________2.虛擬內(nèi)存操作
例如程序顯示了如何分派一個大容量空間,將物理存儲委托給其中的很小一部分(千分之一)并加以使用。
分派和使用大塊內(nèi)存
//工程largealloc
#include#include
//嘗試以指定長度的零數(shù)字填充內(nèi)存塊的簡便方法voidFillZero(LPVOIDpBlock,DWORDdwSize){
_try{
BYTE*arFill=(BYTE*)pBlock;
for(DWORDdwFill=0;dwFill
____________________________________________________________________3)輸入命令,顯示practice目錄中文件和目錄的長列表。創(chuàng)立的目錄列出來了嗎?____________________________________________________________________4)目錄的所有者是?
____________________________________________________________________5)文件的大小是多少?
____________________________________________________________________6)使用file命令確定newdir文件的類型。它是哪一類的文件?
____________________________________________________________________7)假使名字中沒有字符dir,采取別的什么方法來識別出它是一個目錄?
____________________________________________________________________8)mkdir命令創(chuàng)立3個目錄,目錄名分別為high、medium和low,應當使用什么命令?____________________________________________________________________9)用ls命令檢查創(chuàng)立是否成功?步驟17:使用rm命令刪除文件。
rm目錄可以刪除單個文件或多個文件??梢酝ㄟ^在rm命令之后指定文件的名字,或者使用星號(*)和問號(?)元字符,同時刪除幾個文件。在Linux系統(tǒng)中刪除的文件是永遠被刪除了,除非使用圖形界面刪除文件,它們才能夠被恢復。rm命令可以帶–i(交互)選項使用,它在刪除文件之前會提醒用戶。使用rm-i命令作為防范,避免誤刪文件:
rm[-i]filename(s)
1)使用rm命令刪除早先在practice目錄中創(chuàng)立的newfile文件,應當使用什么命令?____________________________________________________________________2)輸入命令顯示practice目錄中文件的長列表。創(chuàng)立的文件還在嗎?
____________________________________________________________________
3)使用帶-i選項的rm命令,刪除早先在practice目錄中創(chuàng)立的filenew文件。交互式選項起到什么作用?
____________________________________________________________________
4)刪除早先創(chuàng)立的三個名為new1、new2和new3的文件。使用問號(?)通配符使用一個命令刪除所有三個文件。使用什么命令?
____________________________________________________________________5)輸入命令,顯示practice目錄中文件的長列表。三個文件還在嗎?
____________________________________________________________________6)還有其他的什么方法來刪除new1、new2和new3文件?
____________________________________________________________________步驟18:使用rm-r命令刪除目錄。
rm-r目錄用于刪除目錄。它將刪除從目標目錄開始的目錄,包括所有的子目錄和文件。當rm命令帶-r信息使用的時候,它可以刪除單個目錄(空或不空)或目錄樹的整節(jié)。rm命令可以帶-i選項使用,它在刪除目錄之前會提醒用戶:
rm–r[i]directory_name(s)
1)刪除早先創(chuàng)立的newdir子目錄,使用什么命令?
____________________________________________________________________2)輸入命令顯示practice目錄中文件的長列表,創(chuàng)立的子目錄還在嗎?
____________________________________________________________________3)改變到早先創(chuàng)立的mediurn子目錄中,輸入什么命令?
____________________________________________________________________4)刪除早先創(chuàng)立的low子目錄,使用什么命令?
____________________________________________________________________5)用相對路徑名和快捷方式,改變回到practice子目錄中,應使用什么命令?
____________________________________________________________________6)使用一個命令刪除high和medium子目錄,應使用什么命令?
____________________________________________________________________步驟19:練習所學習到的內(nèi)容。
通過在practice目錄中創(chuàng)立一個三級的目錄樹,練習使用touch、mkdir和rm命令。試著使
用有意義的目錄名。記住可以使用一個命令創(chuàng)立整個目錄結(jié)構(gòu)。在每個目錄中創(chuàng)立多個文件。記住可以使用一個命令創(chuàng)立多個文件。
終止的時候,請刪除試驗時創(chuàng)立的文件和目錄。步驟20:關(guān)閉終端窗口,注銷。
四、試驗總結(jié)
請總結(jié)一下本次試驗的收獲、教訓和感受,結(jié)合Windows操作系統(tǒng)的相關(guān)內(nèi)容談一下你對
Linux文件操作命令的理解。
//使用虛擬分派以獲得虛擬1GB塊{
LPVOIDpBlock=::VirtualAlloc(NULL,//不指定起始地址c_dwGigabyte,//要求1GBMEM_RESERVE,//不調(diào)配物理存儲PAGE_READWRITE);//對此的讀寫操作::FillZero(pBlock,c_dwMegabyte);
::VirtualFree(pBlock,0,MEM_RELEASE);}
//使用虛擬分派調(diào)配獲得虛擬1GB塊,再為其調(diào)配1MB物理存儲{
LPVOIDpBlock=::VirtualAlloc(NULL,//不指定起始地址c_dwGigabyte,//要求1GBMEM_RESERVE,//不調(diào)配物理存儲PAGE_READWRITE);//對此的讀寫操作::VirtualAlloc(pBlock,c_dwMegabyte,MEM_COMMIT,PAGE_READWRITE);
::FillZero(pBlock,c_dwMegabyte);
::VirtualFree(pBlock,0,MEM_RELEASE);}}
對照運行結(jié)果,分析程序。為了給數(shù)據(jù)庫保存1GB的段地址空間,程序給出了內(nèi)存分派的四種方法。
·第一種技術(shù)
即程序中說明為___________________________________________________的程序段,該段程序試圖利用標準C中的malloc()函數(shù),從已經(jīng)已調(diào)配的小內(nèi)存區(qū)獲得內(nèi)存。從運行結(jié)果看,這種技術(shù)成功了嗎?_____________________。
·其次種技術(shù)
即程序中說明為___________________________________________________的程序段,該段程序試圖通過VirtualAlloc(),然后利用物理備用內(nèi)存將整個塊分派到虛擬內(nèi)存空間的任何位置。這種技術(shù)只對擁有1GB以上的RAM且都有換頁文件的計算機可行。從運行結(jié)果看,這種技術(shù)成功了嗎?_____________________。
·第三種技術(shù)
即程序中說明為___________________________________________________的程序段,該段程序利用VirtualAlloc(),假使函數(shù)成功,則獲得大塊內(nèi)存,但不將任何物理內(nèi)存調(diào)配到此塊中。從運行結(jié)果看,這種技術(shù)成功了嗎?_________________。
·第四種技術(shù)
即程序中說明為___________________________________________________的程序段,該段程序保存1GB的內(nèi)存區(qū),然后將物理內(nèi)存調(diào)配給其中的很小一部分(1MB)。這就是程序介紹的處理一個假想的數(shù)據(jù)庫應用程序的方法:保存整個塊,然后按要求在其一小部分內(nèi)進行讀操作,讓系統(tǒng)將用過的區(qū)域換頁到磁盤中。
利用VirtualLock()API,Windows可用來在自己的進程空間中控制虛擬內(nèi)存的行為。這個函數(shù)與其成對的VirtualUnlock()阻止或允許一塊內(nèi)存從物理RAM中換頁和換頁到頁面文件中。這樣就會通知系統(tǒng)有一段特定的內(nèi)存區(qū)要求對用戶作出猛烈的響應,所以系統(tǒng)不應將其移出RAM。當然,假使要將整個虛擬內(nèi)存空間鎖定,系統(tǒng)就會停留于試圖將系統(tǒng)中工作內(nèi)存的每一小塊換頁到磁盤
3.虛擬內(nèi)存的分派與釋放
能正確使用系統(tǒng)函數(shù)GetMeoryStatus()和數(shù)據(jù)結(jié)構(gòu)MEMORY_STATUS了解系統(tǒng)內(nèi)存和虛擬存儲空間使用狀況,會使用VirsualAlloc()函數(shù)和VirsualFree()函數(shù)分派和釋放虛擬內(nèi)存空間。
//GetMemoryStatus.cpp:Definestheentrypointfortheconsoleapplication.
//
#include\
#include\
#ifdef_DEBUG
#definenewDEBUG_NEW#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;#endif
voidGetMemSta(void);
//TheoneandonlyapplicationobjectCWinApptheApp;usingnamespacestd;
int_tmain(intargc,TCHAR*argv[],TCHAR*envp[]){
intnRetCode=0;LPVOIDBaseAddr;char*str;
GetMemSta();
printf(\
BaseAddr=::VirtualAlloc(NULL,1024*1024*32,MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);//分派虛擬內(nèi)存
if(BaseAddr==NULL)printf(\
str=(char*)malloc(1024*1024*2);//分派內(nèi)存GetMemSta();printf(\
if(::VirtualFree(BaseAddr,0,MEM_RELEASE)==0)//釋放虛擬內(nèi)存printf(\
free(str);//釋放內(nèi)存
GetMemSta();returnnRetCode;
}
voidGetMemSta(void){
MEMORYSTATUSMemInfo;GlobalMemoryStatus(
printf(\
printf(\printf(\vailablePhysicalMemoryis%dMB\\n\vailPhys/(1024*1024));printf(\printf(\vailablePageFileis%dMB\\n\vailPageFile/(1024*1024));printf(\printf(\vailableVirsualmemoryis%dMB\\n\vailVirtual/(1024*1024));printf(\
}
步驟1:在VC6.0環(huán)境下選擇Win32ConsoleApplication建立一個控制臺工程文件,選擇AnapplicationthatSupportsMFC。
步驟2:編輯并編譯完成后,單擊“Build〞菜單中的“BuildGetMemoryStatus.exe〞命令,建立GetMemoryStatus.exe可執(zhí)行文件。
操作能否正常進行?假使不行,則可能的原因是什么?
____________________________________________________________________________________________________________________________________________步驟3:在工具欄單擊“ExecuteProgram〞按鈕,執(zhí)行GetMemoryStatus.cpp.exe程序。分析程序GetMemoryStatus.cpp的運行結(jié)果
1)請描述運行結(jié)果(假使運行不成功,則可能的原因是什么?):
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
2)根據(jù)運行輸出結(jié)果,若要改變分派和回收的虛擬內(nèi)存和物理內(nèi)存的大小,要改變程序代碼的語句,分別為:
________________________________________________________________________________________________________________________________________________3)根據(jù)運行輸出結(jié)果,對照分析4-2程序,可以看出程序運行的流程嗎?請簡單描述:________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
其次部分Linux用戶程序的內(nèi)存管理
現(xiàn)代操作系統(tǒng)允大量個程序同時運行,因此,內(nèi)存中需要同時存放這些程序。操作系統(tǒng)采用的存儲管理方案主要有分區(qū)式存儲管理、分頁式存儲管理、分段式存儲管理和段頁式存儲管理等。本試驗以一個Linux實例程序說明應用程序如何通過系統(tǒng)調(diào)用來管理自己用的空閑內(nèi)存,目的在于了解用戶程序分派內(nèi)存以及回收所用內(nèi)存的程序過程,加深對操作系統(tǒng)存儲管理機制的理解。本試驗實例由my-malloc.h、my-malloc.c和test.c三個文件組成。為閱讀程序便利,對其中的主要函數(shù)作了說明,同學們可結(jié)合程序解釋理解該程序。
本試驗程序主要定義了一個描述自由存儲塊的結(jié)構(gòu),每一個自由塊都包含塊的大小、指向下一塊的指針以及塊區(qū)本身,所有的自由塊以地址增加順序排列,并用鏈表鏈接起來。這一鏈表是本程序維護的一個空閑區(qū)域,對于操作系統(tǒng)的當前記錄來說是已分出去的區(qū)域。由于本程序是運行在用戶態(tài)的程序。
步驟1:單擊紅帽子,在“GNOME幫助〞菜單中單擊“附件〞-“文本編輯器〞命令,在文本編輯中鍵入清單5-4程序并保存為my-malloc.h。
清單5-4my-malloc.h文件
#includetypedeflongAlign;unionheader{struct{
/*foralignmenttolongboundary*//*blockheader:*/
/*nextblockifonFreelist*//*sizeofthisblock*//*forcealignmentofblocks*/
unionheader*next;unsignedintsize;}s;Alignx;};
typedefunionheaderHeader;
#defineNALLOC10/*minimum#unitstorequest*/staticHeader*morecore(unsignedintnu);void*Malloc(unsignedintnbytes);voidFree(void*ap);
步驟2:單擊紅帽子,在“GNOME幫助〞菜單中單擊“附件〞-“文本編輯器〞命令,在文本編輯中鍵入清單5-5程序并保存為my-malloc.c。
清單5-5my-malloc.c文件#include#include“my_malloc.h〞staticHeaderbase;staticHeader*free_list=NULL;
/*empylisttogetstarted*//*startoffreelist*/
/*Malloc:general-purposestorageallocator*/void*Malloc(unsignedintnbytes)
{
Header*p,*prev;unsignedintnunits;
nunits=(nbytes+sizeof(Header)-1)/sizeof(Header)+1;if((prev=free_list)==NULL){
/*nofreelistyet*/
base.s.next=free_list=prev=base.s.size=0;}
for(p=prev->s.next;;prev=p,p=p->s.next){if(p->s.size>=nunits){if(p->s.size==nunits)
/*bigenough*//*exactly*/
prev->s.next=p->s.next;else{
p->s.size-=nunits;p+=p->s.size;p->s.size=nunits;}free_list=prev;return(void*)(p+1);}
if(p==free_list)/*wrappedaroundFreelist*/if((p=morecore(nunits))==NULL)returnNULL;/*noneleft*/}}
/*endfor*/
/*morecore:asksystemformorememory*/staticHeader*morecore(unsignedintnu){
char*cp;Header*up;
if(nus.size=nu;Free(up+1);returnfree_list;}
/*Free:putblockapinFreelist*/voidFree(void*ap){
Header*bp,*p;
bp=(Header*)ap–1;
/*nospaceatall*/
/*pointtoblockheader*/
for(p=free_list;!(bp>pp=p->s.next)
if(p>=p->s.next/*freedblockatstartorendofarena*/if(bp+bp->s.size==p->s.next){/*jointouppernbr*/bp->s.
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五版滅火器經(jīng)銷商招募與培訓合同3篇
- 2025年度冷鏈食品生產(chǎn)項目1#車間能源管理服務合同4篇
- 2025年度土地經(jīng)營權(quán)流轉(zhuǎn)合同范本
- 二零二五年度城市更新項目安置房租賃合同范本3篇
- 2025年陽臺封閉工程節(jié)能環(huán)保材料供應合同2篇
- 二零二五年度在線教育平臺股權(quán)出售合同4篇
- 二零二五版農(nóng)業(yè)機械租賃與供應鏈管理合同4篇
- 二零二五年度電視劇特效制作與采購合同4篇
- 二零二四年度醫(yī)院保潔人員綠化養(yǎng)護與病蟲害防治合同3篇
- 二零二五年度智能交通系統(tǒng)承包商款項安全保障合同4篇
- 無人化農(nóng)場項目可行性研究報告
- 《如何存款最合算》課件
- 社區(qū)團支部工作計劃
- 拖欠工程款上訪信范文
- 2024屆上海市金山區(qū)高三下學期二模英語試題(原卷版)
- 學生春節(jié)安全教育
- 《wifi協(xié)議文庫》課件
- 《好東西》:女作者電影的話語建構(gòu)與烏托邦想象
- 教培行業(yè)研究系列(七):出國考培的再研究供需變化的新趨勢
- GB/T 44895-2024市場和社會調(diào)查調(diào)查問卷編制指南
- 高三日語一輪復習助詞「で」的用法課件
評論
0/150
提交評論