操作系統(tǒng)實(shí)驗(yàn)指導(dǎo)書201603281_第1頁(yè)
操作系統(tǒng)實(shí)驗(yàn)指導(dǎo)書201603281_第2頁(yè)
操作系統(tǒng)實(shí)驗(yàn)指導(dǎo)書201603281_第3頁(yè)
操作系統(tǒng)實(shí)驗(yàn)指導(dǎo)書201603281_第4頁(yè)
操作系統(tǒng)實(shí)驗(yàn)指導(dǎo)書201603281_第5頁(yè)
已閱讀5頁(yè),還剩48頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

PAGE

《操作系統(tǒng)原理》實(shí)驗(yàn)指導(dǎo)書東華大學(xué)計(jì)算機(jī)學(xué)院版本號(hào):V2016修改日期:2016.03.28

實(shí)驗(yàn)一線程創(chuàng)建與撤銷1.1實(shí)驗(yàn)?zāi)康纳钊肜斫饩€程與進(jìn)程的概念,熟悉在Windows環(huán)境下何時(shí)使用進(jìn)程,何時(shí)使用線程。1.2實(shí)驗(yàn)內(nèi)容(1)熟悉VC++、VisualStudio開發(fā)環(huán)境。(2)使用相關(guān)函數(shù)創(chuàng)建和撤銷線程。(3)在一個(gè)進(jìn)程中創(chuàng)建3個(gè)線程,名字分別為threada、threadb、threadc。threada輸出“helloworld!”。threadb輸出“Mynameis…”。threadc輸出“Pleasewait…”,然后sleep5秒鐘,接著輸出“Iwakeup”。1.3預(yù)備知識(shí)1.3.1開發(fā)環(huán)境VisualC++是基于Windows平臺(tái)的可視化集成開發(fā)環(huán)境,和VisualBasic等其他軟件一起構(gòu)成了VisualStudio程序設(shè)計(jì)軟件包。VisualC++提供了Win32控制臺(tái)程序,通過幾個(gè)標(biāo)準(zhǔn)的輸入輸出流進(jìn)行程序與用戶的交互。MSDN為使用微軟程序設(shè)計(jì)語(yǔ)言及其開發(fā)工具的開發(fā)者提供了大量的技術(shù)資料。1.3.2創(chuàng)建線程函數(shù)功能:該函數(shù)創(chuàng)建一個(gè)在調(diào)用進(jìn)程的地址空間中執(zhí)行的線程。函數(shù)原型:HANDLECreateThread(LPSECURITY_ATTRIBUTESlpThreadAttributes,DWORDdwStackSize,LPTHREAD_START_ROUTINElpStartAddress,LPVOIDlpParameter,DWORDdwCreationFlags,LPDWORDlpThreadId);參數(shù)說(shuō)明:lpThreadAttributes:指向一個(gè)SECURITY_ATTRIBUTES結(jié)構(gòu),該結(jié)構(gòu)決定了返回的句柄是否可被子進(jìn)程繼承。若lpThreadAttributes為NULL,則句柄不能被繼承。在WindowsNT中該結(jié)構(gòu)的lpSecurityDescriptor成員定義了新進(jìn)程的安全性描述符。若lpThreadAttributes為NULL,則線程獲得一個(gè)默認(rèn)的安全性描述符。dwStackSize:定義原始堆棧提交時(shí)的大小(按字節(jié)計(jì))。系統(tǒng)將該值舍入為最近的頁(yè)。若該值為0,或小于默認(rèn)時(shí)提交的大小,默認(rèn)情況是使用與調(diào)用線程同樣的大小。更多的信息,請(qǐng)看ThreadStackSize。lpStartAddress:指向一個(gè)LPTHREAD_START_ROUTlNE類型的應(yīng)用定義的函數(shù),該線程執(zhí)行此函數(shù)。該指針還表示潰程進(jìn)程中線程的起始地址。該函數(shù)必須存在于遠(yuǎn)程進(jìn)程中。lpParameter:定義一個(gè)傳遞給該迸程的32位值。dwCreationFIags:定義控制進(jìn)程創(chuàng)建的附加標(biāo)志。若定義了CREATE_SUSPENDED標(biāo)志,線程創(chuàng)建時(shí)處于掛起狀態(tài),并且直到ResumeThread函數(shù)調(diào)用時(shí)d能運(yùn)行。若該值為0,則該線程在創(chuàng)建后立即執(zhí)行。lpThreadId:指向一個(gè)32位值,它接收該線程的標(biāo)識(shí)符。返回值:若函數(shù)調(diào)用成功,返回值為新線程的句柄;若函數(shù)調(diào)用失敗,返回值為NULL。備注:新進(jìn)程的句柄創(chuàng)建時(shí)設(shè)為THREAD_ALL_ACCESS訪問權(quán)限。若未提供安全性描述符,則該句柄可被任何要求一個(gè)線程對(duì)象句柄的函數(shù)所使用。若提供了安全性描述符,則以后使用該句柄時(shí),將在授權(quán)訪問以前執(zhí)行訪問檢查。若訪問檢查拒絕訪問,則請(qǐng)求進(jìn)程不能使用該句柄獲得對(duì)該線程的訪問。線程從lpStartAddress參數(shù)說(shuō)明定義的函數(shù)處開始執(zhí)行。若該函數(shù)返回,系統(tǒng)將默認(rèn)地認(rèn)為以調(diào)用ExitThread函數(shù)的方法終止該線程。使用GetExitCodeThread函數(shù)來(lái)獲得線程的返回值。線程創(chuàng)建時(shí)擁有THREAD_PRIORITY_NORMAL優(yōu)先權(quán)。使用GetThreadPriority和SetThreadPriority函數(shù)可以獲得和設(shè)置線程的優(yōu)先權(quán)值。一個(gè)線程終止時(shí),該線程對(duì)象被設(shè)為發(fā)信號(hào)狀態(tài),以滿足在該對(duì)象上等待的所有進(jìn)程。一個(gè)線程對(duì)象始終存在于系統(tǒng)中,直到該線程終止,且它所有的句柄都已通過調(diào)用。1.3.3撤銷線程函數(shù)功能:該函數(shù)結(jié)束一個(gè)線程。函數(shù)原型:VOIDExitThread(DWORDdwExitCode);參數(shù)說(shuō)明:dwExitCode:定義調(diào)用線程的退出代碼。使用GetExitCodeThread函數(shù)來(lái)檢測(cè)一個(gè)線程的退出代碼。返回值:無(wú)。備注:調(diào)用ExitThread函數(shù),是結(jié)束一個(gè)線程的較好的方法。調(diào)用該函數(shù)后(或者直接地調(diào)用,或者從一個(gè)線程過程返回),當(dāng)前線程的堆棧取消分配,線程終止。若調(diào)用該函數(shù)時(shí),該線程為進(jìn)程的最后一個(gè)線程,則該線程的進(jìn)程也被終止。線程對(duì)象的狀態(tài)變?yōu)榘l(fā)信號(hào)狀態(tài),以釋放所有正在等待該線程終止的其他線程。線程的終止?fàn)顟B(tài)從STILL_ACTIVATE變?yōu)閐wExitCode參數(shù)說(shuō)明的值。線程結(jié)束時(shí)不必從操作系統(tǒng)中移去該線程對(duì)象。當(dāng)線程的最后一個(gè)句柄關(guān)閉時(shí),該線程對(duì)象被刪除。1.3.4終止線程函數(shù)功能:在線程外終止一個(gè)線程,用于強(qiáng)制終止線程。函數(shù)聲明:BOOLTerminateThread(HANDLEhThread,DWORDdwExitCode);參數(shù)說(shuō)明:HANDLEhThread:被終止的線程的句柄,為CWinThread指針。DWORDdwExitCode:退出碼。返回值:函數(shù)執(zhí)行成功則返回非零值,執(zhí)行失敗返回0。調(diào)用getlasterror獲得返回的值。注意:ExitThread()在撤銷線程時(shí)將該線程所擁有的資源全部歸還給系統(tǒng),TerminateThread()不歸還資源。1.3.5掛起線程函數(shù)功能:該函數(shù)對(duì)于指定的時(shí)間間隔掛起當(dāng)前的執(zhí)行線程。函數(shù)原型:VOIDSleep(DWORDdwMilliseconds);參數(shù)說(shuō)明:dwMilliseconds:定義掛起執(zhí)行線程的時(shí)間,以毫秒(ms)為單位。取值為0時(shí),該線程將余下的時(shí)間片交給處于就緒狀態(tài)的同一優(yōu)先級(jí)的其他線程。若沒有處于就緒狀態(tài)的同一優(yōu)先級(jí)的其他線程,則函數(shù)立即返回,該線程繼續(xù)執(zhí)行。若取值為INFINITE則造成無(wú)限延遲。返回值:該函數(shù)沒有返回值。備注:一個(gè)線程可以在調(diào)用該函數(shù)時(shí)將睡眠時(shí)間設(shè)為0ms,以將剩余的時(shí)間片交出。1.3.6關(guān)閉句柄函數(shù)功能:關(guān)閉一個(gè)內(nèi)核對(duì)象。其中包括文件、文件映射、進(jìn)程、線程、安全和同步對(duì)象等。函數(shù)原型:BOOLCloseHandle(HANDLEhObject);參數(shù):hObject:代表一個(gè)已打開對(duì)象的handle。返回值:TRUE:執(zhí)行成功;FALSE:執(zhí)行失敗,可以調(diào)用GetLastError()獲知失敗原因。

實(shí)驗(yàn)二線程同步2.1實(shí)驗(yàn)?zāi)康倪M(jìn)一步認(rèn)識(shí)線程同步的實(shí)質(zhì),學(xué)會(huì)使用信號(hào)量控制線程間的同步。2.2實(shí)驗(yàn)內(nèi)容在程序中使用CreateSemaphore(NULL,0,1,”SemaphoreName1”)創(chuàng)建一個(gè)名為SemaphoreName1的信號(hào)量,其初值為0。使用OpenSemaphore(SYNCHRONIZE|SEMAPHORE__MODIFY_STATE,NULL,”SemaphoreName1”)打開該信號(hào)量。創(chuàng)建一個(gè)子線程,主線程創(chuàng)建子線程后調(diào)WaitForSingleObject(hHandle,INFINITE),這里等待時(shí)間設(shè)置為INFINITE表示要一直等待下去,直到該信號(hào)量被喚醒為止。子線程sleep5秒鐘,然后輸出“Iamover.”結(jié)束,調(diào)用ReleaseSemaphore(hHandle1,1,NULL)釋放信號(hào)量,使信號(hào)量的值加1。2.3預(yù)備知識(shí)2.3.1等待一個(gè)對(duì)象函數(shù)功能:當(dāng)下列情況之一發(fā)生時(shí)該函數(shù)返回:(1)指定對(duì)象處于信號(hào)態(tài);(2)超時(shí)。函數(shù)原型:DWORDWaitForSingleObject(HANDLEhHandle,DWORDdwMilliseconds);參數(shù)說(shuō)明:hHandle:等待對(duì)象句柄。若想了解指定句柄的對(duì)象類型列表,參閱下面?zhèn)渥⒉糠?。在WndowsNT中,句柄必須有SYNCHRONIZE訪問權(quán)限。dwMilliseconds:指定以毫秒為單位的超時(shí)間隔。如果超時(shí),即便對(duì)象的狀態(tài)是非信號(hào)態(tài)的并且沒有完成,函數(shù)也返回。如果dwMilliseconds是0,函數(shù)測(cè)試對(duì)象的狀態(tài)并立刻返回;如果dwMillseconds是INFlNITE,函數(shù)從不超時(shí)。返回值:如果函數(shù)調(diào)用成功,返回值表明引起函數(shù)返回的事件??赡苤等缦拢篧AIT_ABANDONED:指定對(duì)象是互斥對(duì)象,在線程被終止前,線程沒有釋放互斥對(duì)象?;コ鈱?duì)象的所屬關(guān)系被授予調(diào)用線程,并且該互斥對(duì)象被置為非信號(hào)態(tài)。WAIT_OBJEC_O:指定對(duì)象的狀態(tài)被置為信號(hào)態(tài)。WAIT_TlMEOUT:超時(shí),并且對(duì)象的狀態(tài)為非信號(hào)態(tài)。如果函數(shù)調(diào)用失敗,返回值是WAIT_FAILED。若想獲得更多錯(cuò)誤信息,請(qǐng)調(diào)用GetLastError函數(shù)。備注:WaitForSingleObjects函數(shù)決定等待條件是否被滿足。如果等待條件并沒有被滿足,調(diào)用線程進(jìn)人一個(gè)高效的等待狀態(tài),當(dāng)?shù)却凉M足條件時(shí)占用非常少的處理器時(shí)間。在運(yùn)行前,一個(gè)等待函數(shù)修改同步對(duì)象類型的狀態(tài)。修改僅發(fā)生在引起函數(shù)返回的對(duì)象身上。例如,信號(hào)的計(jì)數(shù)減l。WaitForSingleObject函數(shù)能等待的對(duì)象包括:Changenotification(改變通告);Consoleinput(控制臺(tái)輸入);Event(事件);Job(作業(yè));Mutex(互斥對(duì)象);Process(進(jìn)程);Semaphore(信號(hào)量);Thread(線程);Waitabletimer(可等待定時(shí)器)。當(dāng)使用等待函數(shù)或代碼直接或間接創(chuàng)建窗口時(shí),一定要小心。如果一個(gè)線程創(chuàng)建了任何窗口,它必須處理進(jìn)程消息。消息廣播被發(fā)送到系統(tǒng)的所有窗口。一個(gè)線程用沒有超時(shí)的等待函數(shù)也許會(huì)引起系統(tǒng)死鎖。間接創(chuàng)建窗口的兩個(gè)例子是DDE和COMCoInitialize。因此,如果用戶有一個(gè)創(chuàng)建窗口的線程,用MsgWaitForMultipleObjects或MsgWaitForMultipleObjectsEx函數(shù),而不要用SignalObjectAndWait函數(shù)。2.3.2等待多個(gè)對(duì)象函數(shù)功能:WaiForMultipleObjects函數(shù)當(dāng)下列條件之一滿足時(shí)返回:(1)任意一個(gè)或全部指定對(duì)象處于信號(hào)態(tài);(2)超時(shí)間隔已過。函數(shù)原型:DWORDWaitForMultipleObjects(DWORDnCount,CONSTHANDLE*lpHandles,BOOLfWaitAll,DWORDdwMilliSeconds);參數(shù)說(shuō)明:nCount:指定由lpHandles所指向的數(shù)組中的句柄對(duì)象數(shù)目最大對(duì)象句柄數(shù)目MAXIMUM_WAIT_OBJECTS。lpHandles:指向?qū)ο缶浔鷶?shù)組的指針。該數(shù)組可以包含不同類型對(duì)象的句柄。在WindowsNT中,該句柄必須有SYNCHRONIZE訪問權(quán)限。若想獲得更多的信息,請(qǐng)查看StandardAccessRights。fWaitAll:指定等待類型。如果為TRUE,當(dāng)lpHandles指向的數(shù)組里的全部對(duì)象為信號(hào)態(tài)時(shí),函數(shù)返回。如果為FALSE,當(dāng)由lpHandles指向的數(shù)組里的任一對(duì)象為信號(hào)態(tài)時(shí),函數(shù)返回。對(duì)于后者,返回值指出引起函數(shù)返回的對(duì)象。dwMilliseconds:指定以毫秒為單位的超時(shí)間隔。如果超時(shí),即使fWaitAll參數(shù)說(shuō)明指定的條件沒有滿足,函數(shù)也返回。如果dwMilliseconds是0,函數(shù)測(cè)試指定對(duì)象的狀態(tài)并立刻返回。如果dwMilliseconds是INFINITE,函數(shù)從不超時(shí)。返回值:如果函數(shù)調(diào)用成功,返回值表明引起函數(shù)返回的事件??赡苤等缦拢篧AITOBJECT_O到WAIT_OBJECT_O+nCount-l:如果fWaitAll為TRUE,那么返回值表明所有指定對(duì)象的狀態(tài)為信號(hào)態(tài)。如果fWaitAll為FALSE,那么返回值減去WAIT_OBJECT_O表明引起函數(shù)返回的對(duì)象的lpHandles數(shù)組索引。如果多于一個(gè)對(duì)象變?yōu)樾盘?hào)態(tài),則返回的是數(shù)組索引最小的信號(hào)態(tài)對(duì)象索引。WAIT_ABANDONED_O到WAIT_ABANDONED_O+nCount-l:如果fWaitAll為TRUE,那么返回值表明所有指定對(duì)象的狀態(tài)為信號(hào)態(tài),并且至少一個(gè)對(duì)象是已放棄的互斥對(duì)象。如果fWaitAIll為FALSE,那么返回值減去WAIT_ABANDONED_O表明引起函數(shù)返回的放棄互斥對(duì)象的lpHandles數(shù)組索引。WAIT_TIMEOUT:超時(shí)并且由參數(shù)說(shuō)明fWaitAll指定的條件沒有滿足。如果函數(shù)調(diào)用失敗,返回值是WAIT_FAILED。若想獲得更多錯(cuò)誤信息,請(qǐng)調(diào)用GetLastError函數(shù)。2.3.3創(chuàng)建信號(hào)量函數(shù)功能:該函數(shù)是創(chuàng)建一個(gè)有名或者無(wú)名信號(hào)對(duì)象。函數(shù)原型:HANDLECreateSemaphore(LPSECURITY_ATTRIBUTESlpAttributes,LONGlInitialCount,LONGlMaximumCount,LPCTSTRlpName);參數(shù)說(shuō)明:lpAttribute:安全屬性。如果是NULL就表示要使用默認(rèn)屬性。lInitialCount:Semaphore的初值。必須大于或等于0,并且小于或等于MaximumCount。lMaximumCount:Semaphore的最大值。這也就是在同一時(shí)間內(nèi)能夠鎖住Semaphore之線程的最多個(gè)數(shù)。lpName:Semaphore的名稱(一個(gè)字符串).任何線程(或進(jìn)程)都可以根據(jù)這一名稱引用到這個(gè)Semaphore。這個(gè)值可以是NULL,意思是產(chǎn)生一個(gè)沒有名字的Semaphore。返回值:如果成功就傳回一個(gè)handle,否則傳回NULL。不論哪一種情況,GetLastError都會(huì)傳回一個(gè)合理的結(jié)果。如果指定的Semaphore名稱已經(jīng)存在,則函數(shù)還是成功的,GetLastError會(huì)傳回ERROR_ALREADY_EXISTS。2.3.4打開信號(hào)量函數(shù)功能:為現(xiàn)有的一個(gè)已命名信號(hào)機(jī)對(duì)象創(chuàng)建一個(gè)新句柄。函數(shù)原型:HANDLEOpenSemaphore(DWORDdwDesiredAccess,//訪問標(biāo)志BOOLbInheritHandle,//繼承標(biāo)志LPCTSTRlpName//信號(hào)量名);參數(shù)說(shuō)明:dwDesiredAccess可以是下述常數(shù)之一:SEMAPHORE_ALL_ACCESS要求對(duì)事件對(duì)象的完全訪問;SEMAPHORE_MODIFY_STATE允許使用ReleaseSemaphore函數(shù);SYNCHRONIZE允許同步使用信號(hào)機(jī)對(duì)象。bInheritHandle:如果允許子進(jìn)程繼承句柄,則設(shè)為TRUE。lpName:指定要打開的對(duì)象的名字。返回值:如執(zhí)行成功,返回對(duì)象句柄;零表示失敗。會(huì)設(shè)置GetLastError。2.3.5增加信號(hào)量的值函數(shù)功能:該函數(shù)將指定信號(hào)對(duì)象的計(jì)數(shù)增加一個(gè)指定的值。函數(shù)原型:BOOLReleaseSemaphore(HANDLEhSemaphore,LONGlReleaseCount,LPLONGlpPreviousCount)參數(shù)說(shuō)明:hSemaphore:Semaphore的handle。lReleaseCount:Semaphore現(xiàn)值的增額。該值不可以是負(fù)值或0。lpPreviousCount:借此返回Semaphore原來(lái)的值。返回值:如果成功,則返回TRUE。否則返回FALSE。失敗時(shí)可調(diào)用GetLastError獲得原因。備注:無(wú)論ReleaseSemaphore對(duì)于Semaphore所造成的當(dāng)前值怎樣增加,都絕對(duì)不會(huì)超過CreateSemaphore時(shí)所指定的MaximumCount。請(qǐng)記住,lpPreviousCount所傳回來(lái)的是個(gè)瞬間值。你不可以把lReleaseCount加上*lpPreviousCount,就當(dāng)做是semaphore的當(dāng)前值,因?yàn)槠渌€程可能已經(jīng)改變了Semaphore的值。與mutex不同的是,調(diào)用ReleaseSemaphore的那個(gè)線程,并不一定就是調(diào)用WdtXxx的那個(gè)線程。任何線程都可以在任何時(shí)間調(diào)用ReleaseSemaphore,解除被任何線程鎖定的Semaphore。

實(shí)驗(yàn)三線程互斥3.1實(shí)驗(yàn)?zāi)康姆治鼍€程競(jìng)爭(zhēng)資源現(xiàn)象,學(xué)習(xí)解決線程互斥的方法。3.2實(shí)驗(yàn)內(nèi)容在程序中創(chuàng)建兩個(gè)線程h1和h2,定義h1要執(zhí)行的函數(shù)為func1,定義h2要執(zhí)行的函數(shù)為func2。函數(shù)func1和func2都要用到臨界資源count,完成的功能是把count增加1以后輸出。在每個(gè)函數(shù)的定義中,首先調(diào)用EnterCriticalSection函數(shù)進(jìn)入臨界區(qū),完成操作后調(diào)用LeaveCriticalSection函數(shù)退出臨界區(qū)。3.3預(yù)備知識(shí)3.3.1初始化臨界區(qū)函數(shù)功能:該函數(shù)初始化臨界區(qū)對(duì)象。函數(shù)原型:VOIDInitializeCriticalSection(LPCRITICAL_SECTIONlpCriticalSection);參數(shù)說(shuō)明:lpCriticalSectiom:指向臨界區(qū)對(duì)象的指針。備注:?jiǎn)芜M(jìn)程的所有線程可以便用互斥同步機(jī)制的臨界區(qū)對(duì)象。但是,不能保證線程獲得臨界區(qū)所有權(quán)的順序,系統(tǒng)將對(duì)所有線程公平處理。進(jìn)程負(fù)責(zé)分配臨界區(qū)對(duì)象使用的存儲(chǔ)空間,這可以通過聲明CRITICAL_SECTION類型的變量來(lái)完成。在使用臨界區(qū)之前,該進(jìn)程的一些線程必須使用InitializeCriticalSection或InitializeCriticalSectionAndspinCount函數(shù)來(lái)初始化該臨界區(qū)對(duì)象。3.3.2進(jìn)入臨界區(qū)函數(shù)功能:該函數(shù)是等待指定臨界區(qū)對(duì)象的所有權(quán)。當(dāng)調(diào)用線程被賦予所有權(quán)時(shí),該函數(shù)返回。函數(shù)原型:VOIDEnterCriticalSection(LPCRITICAL_SECTIONlpCriticalSection);參數(shù)說(shuō)明:lpCriticalSection:指向臨界區(qū)對(duì)象的指針。3.3.3退出臨界區(qū)函數(shù)功能:該函數(shù)釋放指定臨界區(qū)對(duì)象的所有權(quán)。函數(shù)原型:VOIDLeaveCriticalSection(LPCRITICAL_SECTIONlpCriticalSection);參數(shù)說(shuō)明:lpCriticalSection:指向臨界區(qū)對(duì)象的指針。3.3.4創(chuàng)建互斥對(duì)象函數(shù)功能:創(chuàng)建一個(gè)互斥體。函數(shù)原型:HandleCreateMutex(LPSECURITY_ATTRIBUTESlpMutexAttributes,BOOLbInitialOwner, LPCTSTRlpName );參數(shù)說(shuō)明:lpMutexAttributesSECURITY_ATTRIBUTES:指定一個(gè)SECURITY_ATTRIBUTES結(jié)構(gòu),或傳遞零值(將參數(shù)聲明為ByValAsLong,并傳遞零值),表示使用不允許繼承的默認(rèn)描述符。bInitialOwnerLong:如創(chuàng)建進(jìn)程希望立即擁有互斥體,則設(shè)為TRUE。一個(gè)互斥體同時(shí)只能由一個(gè)線程擁有。lpNameString:指定互斥體對(duì)象的名字。用vbNullString創(chuàng)建一個(gè)未命名的互斥體對(duì)象。如已經(jīng)存在擁有這個(gè)名字的一個(gè)事件,則打開現(xiàn)有的已命名互斥體。這個(gè)名字可能不與現(xiàn)有的事件、信號(hào)機(jī)、可等待計(jì)時(shí)器或文件映射相符。返回值:如執(zhí)行成功,就返回互斥體對(duì)象的句柄;零表示出錯(cuò)。會(huì)設(shè)置GetLastError。即使返回的是一個(gè)有效句柄,但倘若指定的名字已經(jīng)存在,GetLastError也會(huì)設(shè)為ERROR_ALREADY_EXISTS。3.3.5打開互斥對(duì)象函數(shù)功能:為現(xiàn)有的一個(gè)已命名互斥體對(duì)象創(chuàng)建一個(gè)新句柄。函數(shù)原型:HANDLEOpenMutex( DWORDdwDesiredAccess, BOOLbInheritHandle, LPCTSTRlpName);參數(shù)說(shuō)明:dwDesiredAccess可是是下述常數(shù)之一:MUTEX_ALL_ACCESS請(qǐng)求對(duì)互斥體的完全訪問MUTEX_MODIFY_STATE允許使用ReleaseMutex函數(shù)SYNCHRONIZE允許互斥體對(duì)象同步使用bInheritHandle:如希望子進(jìn)程能夠繼承句柄,則為TRUElpName:要打開對(duì)象的名字返回值:如執(zhí)行成功,返回對(duì)象的句柄;零表示失敗。若想獲得更多錯(cuò)誤信息,請(qǐng)調(diào)用GetLastError函數(shù)。3.3.6釋放互斥對(duì)象函數(shù)功能:釋放由線程擁有的一個(gè)互斥體。函數(shù)原型:BOOLReleaseMutex(HANDLEhMutex);參數(shù)說(shuō)明:hMutex:指定一個(gè)互斥體的句柄。返回值:非零表示成功,零表示失敗。會(huì)設(shè)置GetLastError。

實(shí)驗(yàn)四進(jìn)程通信4.1實(shí)驗(yàn)?zāi)康牧私饷艿赖母拍睿W(xué)會(huì)使用命名管道實(shí)現(xiàn)進(jìn)程間的通信。4.2實(shí)驗(yàn)內(nèi)容利用命名管道的相關(guān)知識(shí)及函數(shù),分別編寫服務(wù)器進(jìn)程和客戶端進(jìn)程程序。要求服務(wù)器進(jìn)程和客戶端進(jìn)程程序能夠通過互相傳送數(shù)據(jù)。當(dāng)服務(wù)器進(jìn)程和客戶端進(jìn)程中的任何一端輸入“end”時(shí),結(jié)束會(huì)話。4.3預(yù)備知識(shí)4.3.1建立命名管道函數(shù)功能:創(chuàng)建一個(gè)命名管道。返回的句柄由管道的服務(wù)器端使用。函數(shù)原型:HandleCreateNamedPipe(LPCTSTRlpName,……);參數(shù)說(shuō)明:lpName:指定管道名,采用的形式是:\\.\管道\管道名。最多可達(dá)256個(gè)字符的長(zhǎng)度,而且不用區(qū)分大小寫。如果存在指定名字的一個(gè)管道,則創(chuàng)建那個(gè)管道的一個(gè)新實(shí)例。返回值:如執(zhí)行成功,返回管道的句柄。INVALID_HANDLE_VALUE表示失敗。會(huì)設(shè)置GetLastError。備注:為了能在函數(shù)中取得可變參數(shù),因此至少要一個(gè)普通形參。4.3.2連接命名管道函數(shù)功能:指示一臺(tái)服務(wù)器等待下去,直至客戶機(jī)同一個(gè)命名管道連接。函數(shù)原型:BOOLConnectNamedPipe(HANDLEhNamePipe,OVERLAPPEDlpOverlapped);參數(shù)說(shuō)明:hNamedPipe:管道的句柄。lpOverlapped:如設(shè)為NULL(傳遞ByValAsLong),表示將線程掛起,直到一個(gè)客戶同管道連接為止。否則就立即返回;此時(shí),如管道尚未連接,客戶同管道連接時(shí)就會(huì)觸發(fā)lpOverlapped結(jié)構(gòu)中的事件對(duì)象。隨后,可用一個(gè)等待函數(shù)來(lái)監(jiān)視連接。返回值:如果lpOverlapped為NULL,那么:1)如管道已連接,就返回Ture(非零);如發(fā)生錯(cuò)誤,或者管道已經(jīng)連接,就返回零(GetLastError此時(shí)會(huì)返回ERROR_PIPE_CONNECTED)2)lpOverlapped有效,就返回零;如管道已經(jīng)連接,GetLastError會(huì)返回ERROR_PIPE_CONNECTED;如重疊操作成功完成,就返回ERROR_IO_PENDING。在這兩種情況下,倘若一個(gè)客戶已關(guān)閉了管道,且服務(wù)器尚未用DisconnectNamedPipe函數(shù)同客戶斷開連接,那么GetLastError都會(huì)返回ERROR_NO_DATA。4.3.3拆除命名管道的連接函數(shù)功能:斷開一個(gè)客戶與一個(gè)命名管道的連接。函數(shù)原型:BOOLDisconnectNamedPipe(LonghNamedPipe);參數(shù)說(shuō)明:hNamedPipe:管道的句柄返回值:非零表示成功,零表示失敗。會(huì)設(shè)置GetLastError。備注:為了能在函數(shù)中取得可變參數(shù),因此至少要一個(gè)普通形參。4.3.4客戶端進(jìn)程連接服務(wù)器已建立的命名管道函數(shù)功能:這個(gè)函數(shù)由一個(gè)希望通過管道通信的一個(gè)客戶進(jìn)程調(diào)用。如有可能,它就同一個(gè)管道連接(在必要的情況下等候管道可用)。隨后,它對(duì)指定的數(shù)據(jù)進(jìn)行讀寫,然后將管道關(guān)閉。函數(shù)原型:BOOLCallNamedPipe( StringlpNamedPipeName,//欲打開管道的名稱lpInBufferAny,//要寫入管道的數(shù)據(jù)的內(nèi)存緩沖區(qū)nInBufferSizeLong,//內(nèi)存緩沖區(qū)中的字符數(shù)量lpOutBufferAny, //指定一個(gè)內(nèi)存緩沖區(qū),用于裝載從管道中讀出的數(shù)據(jù)nOutBufferSizeLong,//指定一個(gè)長(zhǎng)整數(shù)變量,用于裝載來(lái)自管道的數(shù)據(jù)lpBytesReadLong,//指定從管道中讀出的字節(jié)數(shù)nTimeOutLong,//管道是否可用及超時(shí)設(shè)置);參數(shù)說(shuō)明:lpNamedPipeName:欲打開管道的名稱lpInBuffer:包含了要寫入管道的數(shù)據(jù)的一個(gè)內(nèi)存緩沖區(qū)nInBufferSize:lpInBuffer緩沖區(qū)中的字符數(shù)量lpOutBuffer:指定一個(gè)內(nèi)存緩沖區(qū),用于裝載從管道中讀出的數(shù)據(jù)nOutBufferSize:指定一個(gè)長(zhǎng)整數(shù)變量,用于裝載來(lái)自管道的數(shù)據(jù)lpBytesRead:指定從管道中讀出的字節(jié)數(shù)。會(huì)閱讀單條消息。如lpOutBuffer的容量不夠大,不能容下整條消息,則函數(shù)會(huì)返回FALSE,而且GetLastError會(huì)設(shè)為ERROR_MORE_DATA(消息中留下的任何字節(jié)都會(huì)丟失)nTimeOutLong,下述常數(shù)之一:NMPWAIT_NOWAIT如管道不可用,則立即返回一個(gè)錯(cuò)誤。NMPWAIT_WAIT_FOREVER永遠(yuǎn)等候管道可用。NMPWAIT_USE_DEFAULT_WAIT使用管道的默認(rèn)超時(shí)設(shè)置,這個(gè)設(shè)置是用CreateNamedPipe函數(shù)指定的。返回值:非零表示成功,零表示失敗。會(huì)設(shè)置GetLastError。4.3.5客戶端進(jìn)程等待命名管道函數(shù)功能:等待命名管道,同時(shí)可以設(shè)置超時(shí)的時(shí)間。函數(shù)原型:BOOLWaitNamedPipe(LPCTSTRlpNamedPipeName,DWORDnTimeOut);參數(shù)說(shuō)明:LpNamedPipeName:要打開的管道名,格式\\servername\pipe\pipename,如果是本地管道則servername可以使用點(diǎn)“.”。nTimeOut等待命名管道的一個(gè)實(shí)例有效的超時(shí)時(shí)間,單位毫秒,也可以使用下面兩個(gè)值中的一個(gè):NMPWAIT_USE_DEFAULT_WAIT0x00000000,使用服務(wù)端CreateNamedPipe創(chuàng)建管道時(shí)設(shè)置的超時(shí)時(shí)間。NMPWAIT_WAIT_FOREVER0xffffffff,一直等到一個(gè)命名管道的實(shí)例有效才返回。返回值:如果在超時(shí)時(shí)間前管道的一個(gè)實(shí)例有效,返回非0;如果超時(shí)時(shí)間內(nèi)沒有一個(gè)有效的實(shí)例,返回0。

實(shí)驗(yàn)五讀者-寫者問題5.1實(shí)驗(yàn)?zāi)康哪軌蚓帉懗绦蚰M讀者-寫者問題。5.2實(shí)驗(yàn)內(nèi)容創(chuàng)建一個(gè)控制臺(tái)進(jìn)程,此進(jìn)程包含n個(gè)線程。用這n個(gè)線程來(lái)表示n個(gè)讀者或?qū)懻摺C總€(gè)線程按相應(yīng)測(cè)試數(shù)據(jù)文件的要求進(jìn)行讀寫操作。用信號(hào)量機(jī)制分別實(shí)現(xiàn)讀者優(yōu)先和寫者優(yōu)先的讀者-寫者問題。讀者-寫者問題的讀寫操作限制(包括讀者優(yōu)先和寫者優(yōu)先):寫-寫互斥,即不能有兩個(gè)寫者同時(shí)進(jìn)行寫操作。讀-寫互斥,即不能同時(shí)有一個(gè)線程在讀,而另一個(gè)線程在寫。讀-讀允許,即可以有一個(gè)或多個(gè)讀者在讀。讀者優(yōu)先的附加限制:如果一個(gè)讀者申請(qǐng)進(jìn)行讀操作時(shí)已有另一個(gè)讀者正在進(jìn)行讀操作,則該讀者可直接開始讀操作。寫者優(yōu)先的附加限制:如果一個(gè)讀者申請(qǐng)進(jìn)行讀操作時(shí)已有另一寫者在等待訪問共享資源,則該讀者必須等到?jīng)]有寫者處于等待狀態(tài)后才能開始讀操作。運(yùn)行結(jié)果顯示要求:要求在每個(gè)線程創(chuàng)建、發(fā)出讀寫操作申請(qǐng)、開始讀寫操作和結(jié)束讀寫操作時(shí)分別顯示一行提示信息,以確定所有處理都遵守相應(yīng)的讀寫操作限制。5.3預(yù)備知識(shí)5.3.1測(cè)試數(shù)據(jù)文件格式測(cè)試數(shù)據(jù)文件包括n行測(cè)試數(shù)據(jù),分別描述創(chuàng)建的n個(gè)線程是讀者還是寫者,以及讀寫操作的開始時(shí)間和持續(xù)時(shí)間。每行測(cè)試數(shù)據(jù)包括四個(gè)字段,各個(gè)字段間用空格分隔。第一字段為一個(gè)正整數(shù),表示線程序號(hào)。第二字段表示相應(yīng)線程角色,R表示讀者,W表示寫者。第三字段為一個(gè)正數(shù),表示讀寫操作的開始時(shí)間:線程創(chuàng)建后,延遲相應(yīng)時(shí)間(單位為秒)后發(fā)出對(duì)共享資源的讀寫申請(qǐng)。第四字段為一個(gè)正數(shù),表示讀寫操作的持續(xù)時(shí)間。當(dāng)線程讀寫申請(qǐng)成功后,開始對(duì)共享資源的讀寫操作,該操作持續(xù)相應(yīng)時(shí)間后結(jié)束,并釋放共享資源。下面是一個(gè)測(cè)試數(shù)據(jù)文件的例子:2W453R524R655W5.13注意:在創(chuàng)建數(shù)據(jù)文件時(shí),由于涉及到文件格式問題,最好在記事本中手工逐個(gè)鍵入數(shù)據(jù),而不要拷貝粘貼數(shù)據(jù),否則,本示例程序運(yùn)行時(shí)可能會(huì)出現(xiàn)不可預(yù)知的錯(cuò)誤。5.3.2實(shí)驗(yàn)提示可以將所有讀者和所有寫者分別存于一個(gè)讀者等待隊(duì)列和一個(gè)寫者等待隊(duì)列中,每當(dāng)讀允許時(shí),就從讀者隊(duì)列中釋放一個(gè)或多個(gè)讀者線程進(jìn)行讀操作;每當(dāng)寫允許時(shí),就從寫者隊(duì)列中釋放一個(gè)寫者進(jìn)行寫操作。1)讀者優(yōu)先讀者優(yōu)先指的是除非有寫者在寫文件,否則讀者不需要等待。所以可以用一個(gè)整型變量read_count記錄當(dāng)前的讀者數(shù)目,用于確定是否需要釋放正在等待的寫者線程(當(dāng)read_count=0時(shí),表明所有的讀者讀完,需要釋放寫者等待隊(duì)列中的一個(gè)寫者)。每一個(gè)讀者開始讀文件時(shí),必須修改read_count變量。因此需要一個(gè)互斥對(duì)象mutex來(lái)實(shí)現(xiàn)對(duì)全局變量read_count修改時(shí)的互斥。另外,為了實(shí)現(xiàn)寫-寫互斥,需要增加一個(gè)臨界區(qū)對(duì)象write。當(dāng)寫者發(fā)出寫請(qǐng)求時(shí),必須申請(qǐng)臨界區(qū)對(duì)象的所有權(quán)。通過這種方法,也可以實(shí)現(xiàn)讀-寫互斥,當(dāng)read_count=l時(shí)(即第一個(gè)讀者到來(lái)時(shí)),讀者線程也必須申請(qǐng)臨界區(qū)對(duì)象的所有權(quán)。當(dāng)讀者擁有臨界區(qū)的所有權(quán)時(shí),寫者阻塞在臨界區(qū)對(duì)象write上。當(dāng)寫者擁有臨界區(qū)的所有權(quán)時(shí),第一個(gè)讀者判斷完"read_count==1"后阻塞在write上,其余的讀者由于等待對(duì)read_count的判斷,阻塞在mutex上。2)寫者優(yōu)先寫者優(yōu)先與讀者優(yōu)先類似;不同之處在于一旦一個(gè)寫者到來(lái),它應(yīng)該盡快對(duì)文件進(jìn)行寫操作,如果有一個(gè)寫者在等待,則新到來(lái)的讀者不允許進(jìn)行讀操作。為此應(yīng)當(dāng)添加一個(gè)整型變量write_count,用于記錄正在等待的寫者的數(shù)目,當(dāng)write_count=0時(shí),才可以釋放等待的讀者線程隊(duì)列。為了對(duì)全局變量write_count實(shí)現(xiàn)互斥,必須增加一個(gè)互斥對(duì)象mutex3。為了實(shí)現(xiàn)寫者優(yōu)先,應(yīng)當(dāng)添加一個(gè)臨界區(qū)對(duì)象read,當(dāng)有寫者在寫文件或等待時(shí),讀者必須阻塞在read上?!ぷx者線程除了要對(duì)全局變量read_count實(shí)現(xiàn)操作上的互斥外,還必須有一個(gè)互斥對(duì)象對(duì)阻塞,read這一過程實(shí)現(xiàn)互斥。這兩個(gè)互斥對(duì)象分別命名為mutex1和mutex2。

實(shí)驗(yàn)六進(jìn)程調(diào)度6.1實(shí)驗(yàn)?zāi)康倪M(jìn)程調(diào)度是處理機(jī)管理的核心內(nèi)容。本實(shí)驗(yàn)要求用C語(yǔ)言編寫和調(diào)試一個(gè)簡(jiǎn)單的進(jìn)程調(diào)度程序。通過本實(shí)驗(yàn)可以加深理解有關(guān)進(jìn)程控制塊、進(jìn)程隊(duì)列的概念,并體會(huì)和了解優(yōu)先數(shù)和時(shí)間片輪轉(zhuǎn)調(diào)度算法的具體實(shí)施辦法。6.2實(shí)驗(yàn)內(nèi)容設(shè)計(jì)進(jìn)程控制塊PCB表結(jié)構(gòu),分別適用于優(yōu)先數(shù)調(diào)度算法和循環(huán)輪轉(zhuǎn)調(diào)度算法。PCB結(jié)構(gòu)通常包括以下信息:進(jìn)程名,進(jìn)程優(yōu)先數(shù)(或輪轉(zhuǎn)時(shí)間片),進(jìn)程所占用的CPU時(shí)間,進(jìn)程的狀態(tài),當(dāng)前隊(duì)列指針等。根據(jù)調(diào)度算法的不同,PCB結(jié)構(gòu)的內(nèi)容可以作適當(dāng)?shù)脑鰟h。建立進(jìn)程就緒隊(duì)列。對(duì)兩種不同算法編制入鏈子程序。編制兩種進(jìn)程調(diào)度算法:①優(yōu)先數(shù)調(diào)度;②循環(huán)輪轉(zhuǎn)調(diào)度。6.3預(yù)備知識(shí)6.3.1實(shí)驗(yàn)提示本程序用兩種算法對(duì)五個(gè)進(jìn)程進(jìn)行調(diào)度,每個(gè)進(jìn)程可有三個(gè)狀態(tài),并假設(shè)初始狀態(tài)為就緒狀態(tài)。初始優(yōu)先數(shù)60。為了便于處理,程序中的運(yùn)行時(shí)間以時(shí)間片為單位計(jì)算,各進(jìn)程的優(yōu)先數(shù)或輪轉(zhuǎn)時(shí)間數(shù)以及進(jìn)程需要運(yùn)行的時(shí)間片數(shù)的初值均由用戶給定。在優(yōu)先數(shù)算法中,進(jìn)程每執(zhí)行一次,優(yōu)先數(shù)減3,CPU時(shí)間片數(shù)加1,進(jìn)程還需要的時(shí)間片數(shù)減1,在輪轉(zhuǎn)算法中,采用固定時(shí)間片,時(shí)間片數(shù)為2,進(jìn)程每執(zhí)行1次,CPU時(shí)間片數(shù)加2,進(jìn)程還需要的時(shí)間數(shù)減2,并排列到就緒隊(duì)列的尾上。6.3.2運(yùn)行結(jié)果示例TYPETHEALGORITHM:(PRIORITY/ROUNDROBIN)PRIORITY(優(yōu)先數(shù)算法)INPUTNAMEANDNEEDTIMEA12A23A34A42A54OUTPUTOFPRIORITY:NAMECPUTIMENEEDTIMEPRIORITYSTATE……………**********************************************************TYPETHEALGORITHM:(PRIORITY/ROUNDROBIN)ROUNDROBIN(時(shí)間片輪轉(zhuǎn)算法)INPUTNAMEANDNEEDTIMEA13A22A34A42A51OUTPUTOFROUNDROBIN:NAMECPUTIMENEEDTIMEROUNDSTATE……………

實(shí)驗(yàn)七存儲(chǔ)管理之動(dòng)態(tài)鏈接庫(kù)7.1實(shí)驗(yàn)?zāi)康睦斫鈩?dòng)態(tài)鏈接庫(kù)的原理,學(xué)會(huì)使用動(dòng)態(tài)庫(kù)編寫程序。7.2實(shí)驗(yàn)內(nèi)容1)編寫動(dòng)態(tài)鏈接庫(kù)實(shí)現(xiàn)如下功能:①求兩個(gè)數(shù)的最大值和最小值;②求1+2+3+4+…+n(n作為一個(gè)參數(shù))。2)編寫程序,通過隱式鏈接和顯式鏈接調(diào)用動(dòng)態(tài)鏈接庫(kù)。7.3預(yù)備知識(shí)7.3.1關(guān)于動(dòng)態(tài)鏈接庫(kù)動(dòng)態(tài)鏈接庫(kù)(DynamicLinkLibrary,DLL)是一個(gè)可執(zhí)行模塊,它包含的函數(shù)可以由Windows應(yīng)用程序調(diào)用以提供所需功能,為應(yīng)用程序提供服務(wù)。動(dòng)態(tài)鏈接庫(kù)文件在Windows系統(tǒng)中的擴(kuò)展名為.dll,它由全局?jǐn)?shù)據(jù)結(jié)構(gòu)、若干函數(shù)組成,運(yùn)行時(shí)被系統(tǒng)加載到進(jìn)程的虛擬地址空間中,成為調(diào)用進(jìn)程的一部分。如果與其他的動(dòng)態(tài)鏈接庫(kù)沒有沖突,該文件通常映射到進(jìn)程虛擬地址空間地址上。當(dāng)進(jìn)程加載動(dòng)態(tài)鏈接庫(kù)時(shí),Windows系統(tǒng)按以下搜索順序查找并加載動(dòng)態(tài)鏈接庫(kù):1)應(yīng)用程序的當(dāng)前目錄2)Windows目錄下3)Windows\System32目錄下4)PATH環(huán)境變量中設(shè)置的目錄5)列入映射網(wǎng)絡(luò)目錄表中的目錄7.3.2動(dòng)態(tài)鏈接庫(kù)入口函數(shù)DllMain()函數(shù)是動(dòng)態(tài)鏈接庫(kù)的入口函數(shù),函數(shù)原型如下:BOOLAPIENTRYDllMain(HANDLEhModule, DWORDul_reason_for_call, LPVOIDlpReserved)hModule:動(dòng)態(tài)鏈接庫(kù)的句柄;reason_for_call:指明系統(tǒng)調(diào)用該函數(shù)的原因;lpReserved:動(dòng)態(tài)鏈接庫(kù)是否需要?jiǎng)討B(tài)加載或卸載。示例:#include"stdafx.h"extern"C"_declspec(dllexport)intAdd(intx,inty);//DLL導(dǎo)出函數(shù),可供應(yīng)用程序調(diào)用extern"C"_declspec(dllexport)intSub(intx,inty);BOOLAPIENTRYDllMain(HANDLEhModule,DWORDul_reason_for_call,LPVOIDlpReserved){returnTRUE;}intAdd(intx,inty){ intz; z=x+y; returnz;}intSub(intx,inty){ intz; z=x-y; returnz;}7.3.3動(dòng)態(tài)鏈接庫(kù)的導(dǎo)入與導(dǎo)出在動(dòng)態(tài)鏈接庫(kù)源程序中聲明導(dǎo)出函數(shù)的代碼如下:_declspec(dllexport)MyDllFunction(intx,inty);其中關(guān)鍵字_declspec(dllexport)表示要導(dǎo)出其后的函數(shù)MyDllFunction()。如果一個(gè)動(dòng)態(tài)鏈接文件中的函數(shù)還需要調(diào)用其他動(dòng)態(tài)鏈接庫(kù),此時(shí),動(dòng)態(tài)鏈接庫(kù)文件除了導(dǎo)出函數(shù)外,還需要一個(gè)導(dǎo)入函數(shù),聲明導(dǎo)入函數(shù)的代碼如下:_declspec(dllimport)DllFunction(intx,inty);動(dòng)態(tài)鏈接庫(kù)的兩種鏈接方式:隱式鏈接和顯式鏈接。7.3.4隱式鏈接應(yīng)用程序的源代碼只引用動(dòng)態(tài)鏈接庫(kù)中包含的符號(hào),當(dāng)應(yīng)用程序運(yùn)行時(shí),加載程序隱式地將動(dòng)態(tài)鏈接庫(kù)裝入到進(jìn)程的地址空間中。隱式鏈接示例:extern“C”_declspec(dllimport)intAdd(intx,inty);intmain(intargc,char*argv[]){intx=7;inty=6;intadd=0;add=Add(x,y);}7.3.5顯式鏈接應(yīng)用程序運(yùn)行時(shí)使用LoadLibrary()顯式地加載所需要的動(dòng)態(tài)鏈接庫(kù),并顯式地鏈接需要的輸出符號(hào)表。隱式鏈接示例:intmain(intargc,char*argv[]){ints=0;typedefint(*pAdd)(intx,inty);pAddadd;HMODULEhDll;hDll=LoadLibrary(“SimpleDll.dll”);add=(pAdd)GetProcAddress(hDll,”ADD”);s=add(6,2);}

實(shí)驗(yàn)八存儲(chǔ)管理之內(nèi)存分配8.1實(shí)驗(yàn)?zāi)康膹牟煌瑐?cè)面了解Windows系統(tǒng)對(duì)用戶進(jìn)程的虛擬內(nèi)存空間的管理和分配方法,同時(shí)了解跟蹤程序的編寫方法(與被跟蹤程序保持同步,使用Windows提供的信號(hào)量),對(duì)Windows分配虛擬內(nèi)存、改變內(nèi)存狀態(tài),以及對(duì)物理內(nèi)存和頁(yè)面文件狀態(tài)查詢的API函數(shù)的功能、參數(shù)限制、使用規(guī)則等進(jìn)一步了解。8.2實(shí)驗(yàn)內(nèi)容1)編寫一個(gè)程序,創(chuàng)建兩個(gè)線程,一個(gè)用于內(nèi)存分配,另一個(gè)用于跟蹤內(nèi)存的分配情況并打印信息。2)將VirtualAlloc函數(shù)的參數(shù)ftAllocahonType分別改為MEM_RESET或MEM_TOP_DOWN,將nProtect參數(shù)分別改為PAGE_GUARD、PAGE_NOACCESS或PAGE_NOCACHE,再進(jìn)行本實(shí)驗(yàn)的各項(xiàng)操作,以及查看內(nèi)存分配的各個(gè)結(jié)果,分析原因。3)嘗試調(diào)換分配、回收、內(nèi)存復(fù)位、加鎖、解鎖、提交、回收的次序,查看結(jié)果,并分析原因。8.3預(yù)備知識(shí)8.3.1查看系統(tǒng)信息函數(shù)功能:該函數(shù)返回當(dāng)前系統(tǒng)的信息。函數(shù)原型:VOIDGetSystemInfo(LPSYSTEM_INFOlpSystemInfo);參數(shù)說(shuō)明:lpSystemInfo:指向SYSTEM_INFO結(jié)構(gòu)的指針,SYSTEM_INFO結(jié)構(gòu)由這個(gè)函數(shù)填充.SYSTEM_INFO結(jié)構(gòu)定義如下:typedefstruct_SYSTEM_INFO{DWORDdwOemld;DWORDdwPageSize;LPVOIDlpMinimumApPlicationAddress;LPVOIDlpMaximumApplicationAddress;DWORDdwActiveProcessorMask;DWORDdwNumberOfProcessors;DWORDdwProcessorType;DWORDdwAllocationGranularity;DWORDdwReserved;}SYSTEM_INFO,*LPSYSTEM_INFO;返回值:該函數(shù)沒有返回值,SYSTEM_INFO結(jié)構(gòu)由這個(gè)函數(shù)填充。頭文件:winbase.h。8.3.2查看系統(tǒng)內(nèi)存信息函數(shù)功能:該函數(shù)可以獲得計(jì)算機(jī)系統(tǒng)中當(dāng)前使用的物理內(nèi)存和虛擬內(nèi)存的信息。函數(shù)原型:VOIDGlobalMemoryStatus(LPMEMORYSTATUSlpBuffer);參數(shù)說(shuō)明:lpBuffer:指向MEMORYSTATUS數(shù)據(jù)結(jié)構(gòu)。GlobalMemoryStatus函數(shù)將內(nèi)存的當(dāng)前信息存儲(chǔ)在該結(jié)構(gòu)中。MEMORYSTATUS結(jié)構(gòu)定義如下:typedefstruct_MEMORVSTATUS{DWORDdwLength;DWORDdwMemoryLoad;DWORDdwTotalPhys;DWORDdwAvailPhys;DWORDdwTotalPageFile;DWORDdwAvailPageFile;DWORDdwTotalVirtual;DWORDdwAvailVirtual;}MEMORYSTATUS,*LPMEMORYSTATUS;返回值:無(wú)。備注:可以使用GlobalMemoryStatus函數(shù)判定你的應(yīng)用程序能夠分配多少與其他應(yīng)用不沖突的內(nèi)存。GlobalMemoryStatus函數(shù)返回的信息是不穩(wěn)定的,不能保證兩次調(diào)用該函數(shù)返回相同的信息結(jié)果。頭文件:winbase.h。8.3.3虛擬內(nèi)存分配函數(shù)功能:該函數(shù)可以在調(diào)用進(jìn)程的虛擬地址中保留或提交頁(yè)面。除非設(shè)置了MEM_RESET標(biāo)志,否則被這個(gè)函數(shù)分配的內(nèi)存單元被自動(dòng)初始化為0。函數(shù)原型:LPVOIDVirtualAlloc(LPVOIDlpAddress,DWORDdwSize,DWORDflAllocationType,DWORDflProtect);參數(shù)說(shuō)明:lpAddress:待分配空間的起始地址。如果指定的內(nèi)存被保留,指定的地址將四舍五入到下一個(gè)64K邊界。如果指定的內(nèi)存已經(jīng)被保留并且被提交,該地址將四舍五入到下一個(gè)頁(yè)面邊界。為了判斷計(jì)算機(jī)中的頁(yè)面大小,可以通過調(diào)用GetSystemInfo函數(shù)獲得。如果該參數(shù)為NULL,將由系統(tǒng)決定分配區(qū)域的地址。dwSize:定義分配空間的大小(以字節(jié)為單位兒如果參數(shù)lpAddress為NULL,dwSize的值將四舍五人到下一個(gè)頁(yè)面邊界。否則,函數(shù)將分配包括從lpAddress到lpAddress+dwSize范圍內(nèi)的所有頁(yè)面。這意味著,當(dāng)一個(gè)2字節(jié)區(qū)域跨過一個(gè)頁(yè)面邊界時(shí),將分配兩個(gè)頁(yè)面。flAllocationType:定義分配類型,可以使用以下標(biāo)志的任何組合定義分配類型:MEM_COMMIT:在內(nèi)存或磁盤頁(yè)面文件中分配物理存儲(chǔ)空間。提交一個(gè)已經(jīng)分配的頁(yè)面將不會(huì)導(dǎo)致函數(shù)失敗。這意味著被提交的或沒有被提交的頁(yè)面都可以再被提交,而不用擔(dān)心會(huì)出錯(cuò)。MEM_RESERVE:保留進(jìn)程的虛擬地址空間,而不分配物理空間。備用的空間在沒有被釋放以前,不能被其他分配操作使用,如Malloc和LocalAlloc函數(shù)等等。備用頁(yè)面可以被隨后使用的VirtualAlloc函數(shù)提交。flProtect:指定存取保護(hù)位的類型。如果頁(yè)面已經(jīng)被提交,則指定下面任何一個(gè)屬性時(shí)應(yīng)該隨同PAGE_GUARD(頁(yè)保護(hù))和PAGE_NOCACHE(頁(yè)無(wú)緩存)這兩個(gè)屬性(關(guān)于PAGE_GUARD和PAGE_NOCACHE的詳細(xì)介紹可以參見MSDN)。PACE_READONW:使被提交的頁(yè)面可讀。試圖在該頁(yè)面中執(zhí)行寫操作將是違法的。如果系統(tǒng)區(qū)分只讀和執(zhí)行,在提交的頁(yè)面中執(zhí)行代碼,將產(chǎn)生違法操作。PAGE_READWRITE:便被提交的頁(yè)面可讀寫。PAGE_EXECUTE:使被提交的頁(yè)面可執(zhí)行,試圖在該頁(yè)面中執(zhí)行讀寫都是違法的。PAGE_EXCUTE_READ:使被提交的頁(yè)面可執(zhí)行和可讀。試圖在該頁(yè)面中執(zhí)行寫操作將是違法的。PAGE_EXCUTE_READWRITE:使被提交的頁(yè)面可執(zhí)行和可讀寫。PAGE_GUARD:保護(hù)標(biāo)志,可以建立保護(hù)頁(yè)面,任何對(duì)于該頁(yè)面的存取會(huì)導(dǎo)致系統(tǒng)產(chǎn)生一個(gè)STATUS_GUARD_PAGE例外,并且關(guān)閉掉保護(hù)頁(yè)面的屬性,所以保護(hù)頁(yè)面的行為像一個(gè)一次性存取警報(bào)器。返回值:如果函數(shù)成功,返回值為所分配的頁(yè)面的基址;如果函數(shù)失敗,返回值為NULL。若想獲得更多錯(cuò)誤信息,請(qǐng)調(diào)用GetLastError函數(shù)。備注:VirtualAlloc函數(shù)執(zhí)行如下操作:1)提交一個(gè)前一個(gè)VirtualAlloc函數(shù)保留的頁(yè)面。2)保留自由頁(yè)面。3)保留并提交自由頁(yè)面。你可以先使用VirtualAlloc函數(shù)保留一塊頁(yè)面,然后再使用VirtualAlloc函數(shù)從保留的內(nèi)存塊中提交一個(gè)頁(yè)面。這樣可以使一個(gè)進(jìn)程保留一定范圍內(nèi)的虛擬地址空間,在不需要使用物理存儲(chǔ)空間時(shí)使用它。每一個(gè)進(jìn)程虛擬地址空間中的頁(yè)面都處于下列狀態(tài)之一:1)Free:自由狀態(tài)。處于該狀態(tài)的頁(yè)面沒有被提交或保留,這個(gè)頁(yè)面對(duì)當(dāng)前的進(jìn)程是不可存取的,VirtualAlloc函數(shù)可以保留或者保留并提交一個(gè)自由頁(yè)面。2)Reserved:保留狀態(tài)。該地址范圍內(nèi)的空間不能被其他分配函數(shù)使用,該頁(yè)面是不可存取的,沒有可用的物理存儲(chǔ)空間與之相連。VirtualAlloc函數(shù)可以保留和提交頁(yè)面,但它不能保留頁(yè)面兩次。VirtualFree函數(shù)可以注銷一個(gè)頁(yè)面,釋放頁(yè)面的存儲(chǔ)空間,而且該函數(shù)還可以同時(shí)注銷和釋放一個(gè)提交頁(yè)面。如果參數(shù)lpAddress的值不為NULL,VirtualAlloc函數(shù)使用lpAddress和dwSize中的值計(jì)算分配頁(yè)面的范圍。所有指定范圍中頁(yè)面的狀態(tài)必須與參數(shù)flAllocType中定義的類型兼容。否則該函數(shù)將失敗,而不分配任何頁(yè)面。3)Commited:提交狀態(tài)。物理存儲(chǔ)已經(jīng)提交給了處于該狀態(tài)的頁(yè)面,而訪問由保護(hù)碼控制。系統(tǒng)只在第一次想要讀取或?qū)懭朐擁?yè)面時(shí),初始化并把每個(gè)提交的頁(yè)面裝入到物理內(nèi)存。當(dāng)該進(jìn)程結(jié)束時(shí),系統(tǒng)會(huì)釋放提交頁(yè)面的物理存儲(chǔ)。函數(shù)VirtualAllocEx可以提交一個(gè)已經(jīng)提交的頁(yè)面;也就是說(shuō)可以提交一系列頁(yè)面,而不考慮它們是否已經(jīng)是提交頁(yè)面,而該函數(shù)不會(huì)出錯(cuò)??梢栽谀骋贿M(jìn)程中使用VirtualFree函數(shù)來(lái)回收(decommit)一個(gè)已經(jīng)提交的頁(yè)面,或者同時(shí)回收并釋放一個(gè)己經(jīng)提交的頁(yè)面。頭文件:winbase.h。8.3.4釋放虛擬空間函數(shù)功能:可以釋放或注銷調(diào)用進(jìn)程虛擬空間中的頁(yè)面。函數(shù)原型:BOOLVirtualFree(LPVOlDlpAddress,DWORDdwSize,DWORDdwFreeType);參數(shù)說(shuō)明:lpAddress:指向釋放頁(yè)面的基址。如果dwFlagType參數(shù)中包括MEM_RELEASE標(biāo)志,當(dāng)該頁(yè)面被保留時(shí),這個(gè)參數(shù)必須是通過VirtualAlIoc函數(shù)返回的基址。dwSize:定義釋放區(qū)域的大小(以字節(jié)位單位),如果dwFlagType參數(shù)中包括MEM_RELEASE標(biāo)志,該參數(shù)的值必須為0;否則地址范圍從lpAddress到lpAddress+dwSize中的頁(yè)面有效。這意味著,釋放一個(gè)跨越邊界的2字節(jié)區(qū)域?qū)⑨尫艃蓚€(gè)頁(yè)面。dwFreeType:定義釋放類型,只能設(shè)置以下標(biāo)志中的一個(gè):MEM_DECOMMIT:注銷提交頁(yè)面,即釋放物理內(nèi)存空間,但在虛擬地址空間仍然保留,如果注銷一個(gè)沒有提交的頁(yè)面將不會(huì)導(dǎo)致函數(shù)失敗。就是說(shuō),提交或沒有提交的頁(yè)面都可以被注銷,而不用擔(dān)心產(chǎn)生錯(cuò)誤。MEM_RELEASE:釋放備用頁(yè)面,即將物理存儲(chǔ)和虛擬地址空間全部釋放。如果設(shè)置了該標(biāo)志,dwSize參數(shù)的值必須是0,否則函數(shù)將失敗。返回值:如果函數(shù)成功,返回一個(gè)非零值;如果函數(shù)失敗,返回值為0。若想獲得更多錯(cuò)誤信息,請(qǐng)調(diào)用GetLastError函數(shù)。備注:VirtualFree函數(shù)執(zhí)行以下操作:1)注銷提交或沒有提交的頁(yè)面。2)釋放備用頁(yè)面。3)注銷并釋放提交或沒有提交的頁(yè)面。為了釋放一片頁(yè)面區(qū)域,要保證該范圍內(nèi)的所有頁(yè)面處于相同狀態(tài)(或者都是備用頁(yè)面或者都是提交頁(yè)面),并且原來(lái)被函數(shù)VirtualAlloc保留的頁(yè)面區(qū)域必須同時(shí)釋放。如果原來(lái)保留的頁(yè)面只有一部分被提交過,你必須首先調(diào)用VirtualFree函數(shù)注銷這些提交的頁(yè)面,然后再調(diào)用VirtualFree函數(shù)釋放它們。被釋放的頁(yè)面可以作為自由頁(yè)面供以后的分配操作使用。對(duì)自由頁(yè)面的讀寫都是違法的操作。VirtualFree函數(shù)可以注銷一個(gè)沒有提交的頁(yè)面,也就是說(shuō),提交或沒有提交的頁(yè)面都可以被注銷,而不用擔(dān)心產(chǎn)生錯(cuò)誤。注銷一個(gè)頁(yè)面可以釋放它在內(nèi)存中的或磁盤上的頁(yè)面文件的物理存儲(chǔ)空間。如果一個(gè)頁(yè)面是被注銷的而不是被釋放的,那么它的狀態(tài)將修改為保留頁(yè)面,它將可以被后面調(diào)用的VinualAlloc函數(shù)提交。對(duì)保留頁(yè)面的讀寫都是違法的操作。該地址范圍中的所有頁(yè)面的狀態(tài)必須與dwFree參數(shù)中設(shè)置的操作類型一致,否則該函數(shù)失敗,而不會(huì)注銷或釋放任何頁(yè)面。頭文件:winbase.h。8.3.5虛擬空間加鎖函數(shù)功能:該函數(shù)可以將進(jìn)程虛擬空間中的內(nèi)存加鎖。以確保后面的對(duì)該區(qū)域的存取操作不會(huì)產(chǎn)生頁(yè)面失敗。函數(shù)原型:BOOLVirtualLocK(LPVOIDlpAddress,DWORDdwSize);參數(shù)說(shuō)明:lpAddress:指向加鎖頁(yè)面區(qū)域基址的指針。dwSize:定義加鎖區(qū)域的大小(以字節(jié)為單位)。有效頁(yè)面的范圍為從lpAddress到lpAddress+dwsize.這意味著,當(dāng)一個(gè)2字節(jié)區(qū)域跨過一個(gè)頁(yè)面邊界時(shí),將兩個(gè)頁(yè)面加鎖。返回值:如果函數(shù)成功,返回一個(gè)非零值;如果函數(shù)失敗,返回值為0。若想獲得更多錯(cuò)誤信息,請(qǐng)調(diào)用GetLastError函數(shù)。備注:指定區(qū)域內(nèi)的所有頁(yè)面必須被提交。被標(biāo)志PAGE_NOACCESS保護(hù)的內(nèi)存不能被加鎖。將頁(yè)面加鎖可能會(huì)減損系統(tǒng)的性能,因?yàn)檫@樣減少了可用的RAM空間,強(qiáng)迫系統(tǒng)將臨界頁(yè)面換到頁(yè)面文件中。默認(rèn)的情況下,一個(gè)進(jìn)程最多可以鎖定30個(gè)頁(yè)面。這個(gè)限制是為了避免對(duì)系統(tǒng)性能的嚴(yán)重影響。如果一個(gè)應(yīng)用需要將更多的頁(yè)面加鎖,必須首先調(diào)用SetProcessWorkingSetSize函數(shù)來(lái)增加它們的工作集的最大和最小值。即使進(jìn)程是空閑的,加鎖的頁(yè)面也保持常駐。為了將一塊加鎖的區(qū)域解鎖,可以使用VirtualUnlock函數(shù)。當(dāng)進(jìn)程結(jié)束時(shí),加鎖的頁(yè)面自動(dòng)解鎖。這個(gè)函數(shù)與GlobalLock或LocalLock函數(shù)不同的是:它不遞增加鎖次數(shù)和將句柄轉(zhuǎn)化為指針。虛擬頁(yè)面沒有加鎖的次數(shù),因此解鎖一些頁(yè)面區(qū)域不必多次調(diào)用VinualUnlock。頭文件:winbase.h。8.3.6虛擬空間解鎖函數(shù)功能:該函數(shù)可以將進(jìn)程虛擬空間指定范圍內(nèi)的頁(yè)面解鎖,從而系統(tǒng)在必要時(shí)可以將這些頁(yè)面換出到頁(yè)面文件中。函數(shù)原型:BOOLVirtualUnLock(LPVOIDlpAddress,DWORDdwSize);參數(shù):lpAddress:指向加鎖頁(yè)面區(qū)域基址的指針。dwSize:定義加鎖區(qū)域的大小(以字節(jié)為單位)。有效頁(yè)面的范圍為從lpAddress到lpAddress+dwsize.這意味著,當(dāng)一個(gè)2字節(jié)區(qū)域跨過一個(gè)頁(yè)面邊界時(shí),將兩個(gè)頁(yè)面加鎖。返回值:如果函數(shù)成功,返回一個(gè)非零值;如果函數(shù)失敗,返回值為0。若想獲得更多錯(cuò)誤信息,請(qǐng)調(diào)用GetLastError函數(shù)。備注:解鎖的內(nèi)存范圍不要求一定與調(diào)用VirtualLock函數(shù)加鎖的范圍相匹配,但是該范圍中的頁(yè)面必須是加鎖的。CreateThread、CreateSemaphOre、WaitForMultipleObjects、WaitForSingleObject、ReleaseSemaphore和Sleep可以參見讀者寫者問題的相關(guān)API函數(shù)。頭文件:winbase.h。

實(shí)驗(yàn)九存儲(chǔ)管理之頁(yè)面置換算法9.1實(shí)驗(yàn)?zāi)康拇鎯?chǔ)管理的主要功能之一是合理地分配空間。請(qǐng)求頁(yè)式管理是一種常用的虛擬存儲(chǔ)管理技術(shù)。本實(shí)驗(yàn)的目的是通過請(qǐng)求頁(yè)式存儲(chǔ)管理中頁(yè)面置換算法模擬設(shè)計(jì),了解虛擬存儲(chǔ)技術(shù)的特點(diǎn),掌握請(qǐng)求頁(yè)式管理的頁(yè)面置換算法。9.2實(shí)驗(yàn)內(nèi)容通過隨機(jī)數(shù)產(chǎn)生一個(gè)指令序列,共320條指令,指令的地址按下述原則生成:50%的指令是順序執(zhí)行的;25%的指令是均勻分布在前地址部分。25%的指令是均勻分布在后地址部分。具體的實(shí)施辦法是:在[0,319]的指令地址之間隨機(jī)選取一點(diǎn)m;順序執(zhí)行一條指令,即執(zhí)行地址為m+1的指令;在前地址[0,m+1]中隨機(jī)選取一條指令并執(zhí)行,該指令的地址為m’;順序執(zhí)行一條指令,其地址為m’+1;在后地址[m’+2,319]中隨機(jī)選取一條指令并執(zhí)行;重復(fù)上述步驟——,直到執(zhí)行320次指令。將指令序列變換成頁(yè)地址流,設(shè):頁(yè)面大小為1K;用戶內(nèi)存容量為4頁(yè)到32頁(yè);用戶虛存容量為32K。在用戶虛存中,按每K存放10條指令排列虛存地址,即320條指令在虛存中的存放方式為:第0條-9條指令為第0頁(yè)(對(duì)應(yīng)虛存地址為[0,9]);第10條-第19條指令為第一頁(yè)(對(duì)應(yīng)虛存地址為[10,19]);……第310條-第319條指令為第31頁(yè)(對(duì)應(yīng)虛存地址為[310,319])。按以上方式,用戶指令可組成32頁(yè)。計(jì)算并輸出下述各種算法在不同內(nèi)存容量下的命中率:先進(jìn)先出的算法(FIFO);最近最少使用算法(LRR);最佳淘汰算法(OPT);先淘汰最不常用的頁(yè)地址;最少訪問頁(yè)面算法(LFR);最近不經(jīng)常使用算法(NUR);其中和為選擇內(nèi)容。命中率=1-頁(yè)面失效次數(shù)/頁(yè)地址流長(zhǎng)度。在本實(shí)驗(yàn)中,頁(yè)地址流長(zhǎng)度為320,頁(yè)面失效次數(shù)為每次訪問相應(yīng)指令時(shí),該指令所對(duì)應(yīng)的頁(yè)不在內(nèi)存的次數(shù)。9.3預(yù)備知識(shí)9.3.1實(shí)驗(yàn)提示關(guān)于隨機(jī)數(shù)產(chǎn)生辦法,可用函數(shù)RAND()產(chǎn)生隨機(jī)數(shù)。9.3.2運(yùn)行結(jié)果示例FIFOLRUOPT456……32

實(shí)驗(yàn)十設(shè)備管理10.1實(shí)驗(yàn)?zāi)康牧私獯疟P的基本結(jié)構(gòu),熟悉Windows環(huán)境下磁盤的讀寫編程。10.2實(shí)驗(yàn)內(nèi)容1)實(shí)現(xiàn)獲取當(dāng)?shù)卮疟P(如C:盤、D:盤、E:盤等)的詳細(xì)信息。2)讀/寫磁盤指定位置信息。10.3預(yù)備知識(shí)10.3.1磁盤基本物理結(jié)構(gòu)typedefstruct_DISK_GEOMETRY{LARGE_INTEGERCylinders; //磁盤柱面數(shù)MEDIA_TYPEMediaType; //介質(zhì)類型DWORDTracksPerCylinder; //每個(gè)柱面的磁道數(shù)DWORDSectorsPerTrace; //每個(gè)磁道的扇區(qū)數(shù)DWORDBytesPerSector; //每個(gè)扇區(qū)的字節(jié)數(shù)}DISK_GEOMETRY;使用說(shuō)明:要想使用DISK_GEOMETRY結(jié)構(gòu),需要引入頭文件winioctl.h。#include“winioctl.h”1)文件創(chuàng)建:函數(shù)CreateFile()用于打開磁盤驅(qū)動(dòng)器并返回一個(gè)文件句柄,這里驅(qū)動(dòng)器被當(dāng)做文件處理。HANDLECreateFile(LPCTSTRlpFileName, //指向文件名指針DWORDdwDesiredAccess,//讀/寫訪問模式DWORDdwShareMode, //共享模式LPSECURITY_ATTRIBUTESlpSecurityAttributes,//指向安全屬性的指針DWORDdwCreationDisposition,//文件存在標(biāo)志DWORDdwFlagsAndAttributes,//文件屬性HANDLEhTemplateFile//指向訪問模板文件的句柄)具體參數(shù)以及返回值請(qǐng)參見第九個(gè)實(shí)驗(yàn)。10.3.2獲取磁盤的基本信息函數(shù)原型:BOOLDeviceIoControl(HANDLEhDevice,//設(shè)備句柄DWORDdwIoControlCode,//操作控制代碼LPVOIDlpInBuffer,//輸入數(shù)據(jù)緩沖區(qū)DWORDnInBufferSize,//輸入數(shù)據(jù)緩沖區(qū)大小LPVOIDlpOutBuffer,//輸出數(shù)據(jù)緩沖區(qū)DWORDnOutBufferSize,//輸出數(shù)據(jù)緩沖區(qū)大小LPDWORDlpBytesReturned, //可獲取的字節(jié)計(jì)數(shù)LPOVERLAPPEDlpOverlapped//指向OVERLAPPED結(jié)構(gòu)的指針)主要參數(shù)說(shuō)明:dwIoControlCode:指定操作的控制信息,用該值可以辨別將要執(zhí)行的操作,以及對(duì)哪類設(shè)備進(jìn)行操作。該參數(shù)取值如下表:值描述IOCTL_DISK_GET_DRIVE_GEOMETRY得到磁盤物理結(jié)構(gòu)信息IOCTL_DISK_PARTITION_INFO得到磁盤分區(qū)信息FSCTL_QUERY_FAT_BPB返回FAT16或FAT12卷的前36字節(jié)FSCTL_COMPRESSION獲取文件或目錄的壓縮信息返回值:如果函數(shù)調(diào)用成功,則返回值為非0。如果函數(shù)調(diào)用失敗備注:1)CreateFile這個(gè)函數(shù)用處很多,本次實(shí)驗(yàn)用它“打開”設(shè)備驅(qū)動(dòng)程序,得到設(shè)備的句柄。2)與普通文件名有所不同,設(shè)備驅(qū)動(dòng)的“文件名”(常稱為“設(shè)備路徑”)形式固定為“\\.\DeviceName”(注意在C程序中該字符串寫法為“\\\\.\\DeviceName”),DeviceName必須與設(shè)備驅(qū)動(dòng)程序內(nèi)定義的設(shè)備名稱一致。3)一般地,調(diào)用CreateFile獲得設(shè)備句柄時(shí),訪問方式參數(shù)設(shè)置為0或GENERIC_READ|GENERIC_WRITE,共享方式參數(shù)設(shè)置為FILE_SHARE_READ|FILE_SHARE_WRITE,創(chuàng)建方式參數(shù)設(shè)置為OPEN_EXISTING,其它參數(shù)可設(shè)置為0或NULL。示例:FloopyDisk=CreateFile(device, GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,OPEN_EXISTING,FILE_FLAG_RANDOM_ACCESS|FILE_FLAG_NO_BUFFERING,NULL);10.3.3設(shè)置讀/寫操作的位置函數(shù)原型:DWORDSetFilePointer(HANDLEhFile, //文件句柄LONGlpDistanceToMove,//文件指針要移動(dòng)的偏移量的低32位PLONGlpDistanceToMoveHigh,//文件指針要移動(dòng)的偏移量的高32位DWORDdwMoveMethod //移動(dòng)起點(diǎn))dwMoveMethod:文件指針移動(dòng)的初始位置,其值可取下表中的數(shù)值。值描述FILE_BEGIN開始點(diǎn)為0或者為文件的開始位置FILE_CURRENT開始點(diǎn)為文件指針的當(dāng)前位置FILE_END開始點(diǎn)為文件的結(jié)尾位置返回值:如果函數(shù)調(diào)用成功,而且lpDistanceToMoveHigh為空,返回值為文件指針的低32位DWORD類型值。如果參數(shù)lpDistanceToMoveHigh不為空,返回值為文件指針的低32位DWORD類型值,并且高32位DWORD類型值輸出到一個(gè)long類型的參數(shù)中。

實(shí)驗(yàn)十一文件管理之文件讀寫11.1實(shí)驗(yàn)?zāi)康睦斫釽indows的文件管理方法,學(xué)會(huì)采用不同的方式實(shí)現(xiàn)文件讀寫。通過對(duì)無(wú)緩沖、有緩沖和異步三種方式實(shí)現(xiàn)文件操作的比較,進(jìn)一步理解操作系統(tǒng)有關(guān)文件系統(tǒng)I/O的概念,為選擇文件I/O方式提供依據(jù)。11.2實(shí)驗(yàn)內(nèi)容1)創(chuàng)建文件:源文件source1.txt、source2.txt、source3.txt和目標(biāo)文件dest1.txt、dest2.txt、dest3.txt。文件source1.txt、source2.txt和source3.txt內(nèi)容完全相同。2)創(chuàng)建三個(gè)線程,每個(gè)線程分別實(shí)現(xiàn):①?gòu)奈募ource1.txt中讀取內(nèi)容并寫到文件dest1.txt中,采用無(wú)緩沖方法實(shí)現(xiàn)文件讀/寫。②從文件source2.txt中讀取內(nèi)容并寫到文件dest2.txt中,采用高速緩存實(shí)現(xiàn)文件讀/寫。③從文件source3.txt中讀取內(nèi)容并寫到文件dest3.txt中,采用異步方式實(shí)現(xiàn)文件讀/寫。3)比較三種方式下文件讀寫速度(消耗時(shí)間)。11.3預(yù)備知識(shí)11.3.1創(chuàng)建文件函數(shù)功能:該函數(shù)創(chuàng)建一個(gè)文件。函數(shù)原型:HANDLECreateFile(LPCTSTRlpFileName,//指向文件名指針DWORDdwDesiredAccess,//讀/寫訪問模式DWORDdwShareMode,//共享模式LPSECURITY_ATTRIBUTESlpSecurityAttributes,//指向安全屬性的指針DWORDdwCreationDisposition,//文件存在標(biāo)志DWORDdwFlagsAndAttributes,//文件屬性HANDLEhTemplateFile//指向訪問模板文件的句柄)參數(shù)說(shuō)明:1)dwDesiredAccess:指出訪問文件的類型,可以是讀、寫、讀/寫訪問或者查詢?cè)L問。該參數(shù)可以是下表中的組合。值描述0查詢?cè)L問GENERIC_READ讀訪問,從文件中讀出數(shù)據(jù),且移動(dòng)文件指針,當(dāng)對(duì)文件進(jìn)行讀/寫時(shí),該屬性可與GENERIC_WRITE組合使用GENERIC_WRITE讀訪問,將數(shù)據(jù)寫入文件,且移動(dòng)文件指針,當(dāng)對(duì)文件進(jìn)行讀/寫時(shí),該屬性可與GENERIC_READ組合使用2)dwShareMode:指出文件共享模式。若dwShareMode的值為0,表示目標(biāo)不能被共享。若要共享文件,可以使用下表中的組合。值描述FILE_SHARE_DELETE僅當(dāng)刪除訪問時(shí),對(duì)文件的打開操作才能成功FILE_SHARE_READ僅當(dāng)讀訪問時(shí),對(duì)文件的打開操作才成功FILE_SHARE_WRITE僅當(dāng)寫訪問時(shí),對(duì)文件的打開操作才成功3)dwCreationDisposition:文件存在標(biāo)志。指出文件不存在時(shí),可以對(duì)文件進(jìn)行何種操作??梢匀∠卤碇械慕M合。值描述CREATE_NEW創(chuàng)建新文件。若文件已存在,則調(diào)用函數(shù)失敗CREATE_ALWAYS創(chuàng)建新文件。若文件已存在,則該函數(shù)覆蓋原文件的內(nèi)容且清空現(xiàn)有屬性。OPEN_EXISTING打開已存在的文件,若文件不存在,則該函數(shù)打開失敗OPEN_ALWAYS若文件已存在,則打開該文件;若文件不存在,則以CREATE_NEW方法創(chuàng)建文件TRUNCATE_EXISTING打開文件,并將文件的大小截取為04)dwFlagsAndAttributes:指出文件屬性和標(biāo)志。除了FILE_ATTRIBUTE_NORMAL屬性外,參數(shù)還可以取下表中任何屬性的組合。值描述FILE_ATTRIBUTE_ARCHIVE文件可以被存檔FILE_ATTRIBUTE_HIDDEN文件可以被隱藏FILE_ATTRIBUTE_NORMAL文件沒有其他屬性,該屬性僅當(dāng)單獨(dú)使用時(shí)才有效FILE_ATTRIBUTE_OFFLINE文件中的數(shù)據(jù)被脫機(jī)存儲(chǔ),文件中的數(shù)據(jù)不能立即有效FILE_ATTRIBUTE_READONLY文件只能讀FILE_ATTRIBUTE_SYSTEM文件被系統(tǒng)使用FILE_ATTRIBUTE_TEMPORARY文件被臨時(shí)存儲(chǔ)參數(shù)dwFlagsAndAttributes還可以取下面表中任何屬性的組合。值描述FILE_FLAG_WRITE_THROUGH系統(tǒng)對(duì)文件的任何寫操作,當(dāng)緩沖的內(nèi)容改變時(shí)立即寫回磁盤FILE_FLAG_OVERLAPPED異步讀/寫,使用該屬性時(shí),文件指針將不被保留FILE_FLAG_NO_BUFFERING文件不適用緩沖FILE_FLAG_RANDOM_ACCESS文件

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論