版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
將要介紹Windows98和Windows2000使用的一些算法。上章紹每線如擁一上結(jié)的這結(jié)程核象這個上下文結(jié)構(gòu)反映了線程上次運(yùn)行時該線程的CP寄存器的狀態(tài)。每隔20ms左右,indows要查看當(dāng)前存在的所有線程內(nèi)核對象。在這些對象中,只有某些對象被視為可以調(diào)度的對象。indowsCP的寄存器中,它的值是上次保存的境的這操稱上轉(zhuǎn)。indows實際上保存了一個記錄,它說明每個線程獲得了多少個運(yùn)行機(jī)會。使用了37379次。目前,線程正在執(zhí)行代碼,并對它的進(jìn)程的地址空間中的數(shù)據(jù)進(jìn)行操作。再過20ms左右,Windows就將CPU的寄存器重新保存到線程的上下文中。線程不再運(yùn)行。系統(tǒng)再次查看其余的可CP的寄存器中,然后繼續(xù)運(yùn)行。當(dāng)系統(tǒng)引導(dǎo)時,便開始加載線程的上
圖7-1indows線程操作系統(tǒng),因為一個線程可以隨時停止運(yùn)行,隨后另一個線程可進(jìn)行調(diào)度。如你所見,可以對它進(jìn)行一定程度的控制,但是不能太多。記住,無法保證線程總是能夠運(yùn)行,也不能保證線程能夠得到整個進(jìn)程,無法保證其他線程不被允許運(yùn)行等等。注意程序員常常問我,如何才能保證線程在某個的某個時間段內(nèi)開始運(yùn)行,比1ms內(nèi)開始運(yùn)行呢?我的回答是,辦不到。實時操作系統(tǒng)才能作出這樣的承諾,但是indow實時操作系統(tǒng)必須清楚地知道它是在什么硬件上運(yùn)行,這樣它才能知道它的硬盤控制器和鍵盤等的等待時間。對indows規(guī)定的目標(biāo)是,使它能夠在各種不同的硬件上運(yùn)行,即能夠在不同的CPU、不同的驅(qū)動器和不同的網(wǎng)絡(luò)上運(yùn)行。簡而言之,indows沒有設(shè)計成為一種實時操作系統(tǒng)。盡管應(yīng)強(qiáng)調(diào)這樣一個概念,即系統(tǒng)只調(diào)度可以調(diào)度的線程,但是實際情況是,系統(tǒng)中的大多數(shù)線程是不可調(diào)度的線程。例如,有些線程對象的暫停計數(shù)大于1。這意味著該線程已經(jīng)暫停運(yùn)行,不應(yīng)該給它安排任何CPU時間。通過調(diào)用使用CREATE_SUSPENDED標(biāo)志的CreateProcess或CreateThread函數(shù),可以創(chuàng)建一個暫停的線程。(本章后面還要介紹除了暫停的線程外,其他許多線程也是不可調(diào)度的線程,因為它們正在等待某些事情的發(fā)生。例如,如果運(yùn)行Notepad,但是并不鍵入任何數(shù)據(jù),那么Notepa的線程就沒有什么事情要做。系統(tǒng)不給無事可做的線程分配CPU時間。當(dāng)移動Notepa的窗口時,或者NotepadNotepadNotepad這并不意味著Notepa除了暫停的線程外,其他許多線程也是不可調(diào)度的線程,因為它們正在等待某些事情的發(fā)生。例如,如果運(yùn)行Notepad,但是并不鍵入任何數(shù)據(jù),那么Notepa的線程就沒有什么事情要做。系統(tǒng)不給無事可做的線程分配CPU時間。當(dāng)移動Notepa的窗口時,或者NotepadNotepadNotepad這并不意味著Notepad的線程立即獲得了CPU時間。它只是表示Notepad的線程有事情可做,系統(tǒng)將設(shè)法在某個時間() 程內(nèi)核對象的內(nèi)部有一個值,用于指明線程的暫停計數(shù)。當(dāng)調(diào)用CreateProcess或CreateThread函數(shù)時,就創(chuàng)建了線程的內(nèi)核對象,并且它的暫停計數(shù)被初始化為1。這可以防止線程被調(diào)度到CPU用ResumeThread,將調(diào)用CreateThread函數(shù)時返回的線程句柄傳遞給它(或者是將傳遞給如果ResumeThread單個線程可以暫停若干次。如果一個線程暫停了3次,它必須恢復(fù)3次,然后它才可以被分配給一個CPU。當(dāng)創(chuàng)建線程時,除了使用CREATE_SUSPENDED外,也可以調(diào)用Suspend任何線程都可以調(diào)用該函數(shù)來暫停另一個線程的運(yùn)行(只要擁有線程的句柄。不用說,線可自暫運(yùn)但不自恢行與ResumeThread,SuspendThread的是線程的前一個暫停數(shù)。線程暫停的多次數(shù)可是 UM_SUSPEND_COUNT次(在WinNT.h中定義為127。注意,SuspendThread與內(nèi)核方式的執(zhí)行是異步進(jìn)行的,但是在實際環(huán)境中,調(diào)用SupendThread時必須,因為不知道暫停線程運(yùn)行時它在進(jìn)行什么操作。如果線程試圖從堆棧中分配內(nèi)存,那么該線程將在該堆棧上設(shè)置一個鎖。當(dāng)其他線程試圖該堆棧時,這些線程的就被停止,直到第一個線程恢復(fù)運(yùn)行。只有確切知道目標(biāo)線程是什么的問題或死鎖狀態(tài),紹對于Windows來說,不存在暫?;蚧謴?fù)進(jìn)程的概念,因為進(jìn)程從來不會被安排獲得CPU時間。但是,曾經(jīng)有人無數(shù)次問我如何暫停進(jìn)程中的所有線程的運(yùn)行。Windows確實允許一個進(jìn)indows沒有提供其他方法來暫停進(jìn)程中所有線程的運(yùn)行。例如,雖然許多線程已經(jīng)暫停,但是仍然可以創(chuàng)建新線程。從某種意義上說,系統(tǒng)必須在這個時段內(nèi)暫停所有新線程的運(yùn)行。已經(jīng)將這項功能納入了統(tǒng)的調(diào)試機(jī)制。雖然無法創(chuàng)建絕對完美的SuspendProcess函數(shù),但是可以創(chuàng)建一個該函數(shù)的實現(xiàn)代碼,它能夠在許多條件下出色地運(yùn)行。下面是我的SuspendProces我的SuspendProcess函數(shù)使用oolHelp函數(shù)來枚舉系統(tǒng)中的線程列表。當(dāng)我找到作為指定進(jìn)程的組成部分的線程時,我調(diào)用OpenThread:這個新Windows2000ID的線程內(nèi)核對象,對內(nèi)核對象的使用計數(shù)進(jìn)行遞增,然后返回對象的句柄。運(yùn)用這個句柄,我調(diào)用SuspendThread(或ResumeThread)。由于OpenThread在Windows2000中是個新函數(shù),因此我的SuspendProces函數(shù)在Windos95或Windos98上無法運(yùn)行,在WindosT.0或更早的版本上也無法運(yùn)行。也許你懂得為什么SuspendProcess不能總是運(yùn)行,原因是當(dāng)枚舉線程組時,新線程可以被創(chuàng)建和撤消。因此,當(dāng)我調(diào)用Createoolhelp32Snapshot后,一個新線程可能會出現(xiàn)在目標(biāo)進(jìn)程中,我的函數(shù)將無法暫停這個新線程。過了一些時候,當(dāng)調(diào)用SuspendProcess函數(shù)來恢復(fù)線程IDID。這將會導(dǎo)致該函數(shù)暫停任意些個(也許在目標(biāo)進(jìn)程之外的一個進(jìn)程中的)線程的運(yùn)行。 100ms,那么可以睡眠大約這么長時間,但是也可能睡眠數(shù)秒鐘或者數(shù)分鐘。記住,Windows不是個實時操作系統(tǒng)。雖然線程可能在規(guī)定的時間被喚醒,但是它能否做到,取決于系統(tǒng)可以調(diào)用Sleep,并且為dwMilliseconds參數(shù)傳遞INFINITE。這將告訴系統(tǒng)不要調(diào)度可以將0傳遞給Sleep。這將告訴系統(tǒng),調(diào)用線程將釋放剩余的時間片,并迫使系統(tǒng)調(diào)度另一個線程。但是,系統(tǒng)可以對剛剛調(diào)用Sleep的線程重新調(diào)度。如果不存在多個擁有相SwitchoThread的函數(shù),使得另一個可調(diào)度線程(如果存在能夠運(yùn)行:當(dāng)調(diào)用這個函數(shù)的時候,系統(tǒng)要查看是否存在一個迫切需要CPU時間的線程。如果沒有線SwitchToThread就對該線程進(jìn)行調(diào)度(該線程的優(yōu)先級可能低于調(diào)用SwitchToThread的線程。該資源。如果調(diào)用SwitchToThread函數(shù)時沒有其他線程能夠運(yùn)行,那么該函數(shù)返回FALSE,否調(diào)用SwitchToThread函數(shù)與調(diào)用Sleep是相似的,并且傳遞給它一個0ms的超時。差別是SwitchToThread允許優(yōu)先級較低的線程運(yùn)行。即使低優(yōu)先級線程迫切需要CPU時間,Sleep也能Windows98Windows98有時想要計算線程執(zhí)行某個任務(wù)需要多長的時間。許多人采取的辦法是編寫類似下面的代碼:這個代碼做了一個簡單的假設(shè):即它不會被中斷。但是,在搶占式操作系統(tǒng)中,無法知道線程何時被賦予CP時間。當(dāng)取消線程的CPU時間時,就更難計算線程執(zhí)行不同任務(wù)時所PUindows提供了一個稱為GetThreadime表7-1GetThreadTimes時間 用英國時間日午夜后ns的時間間隔表示 用英國時間日午夜后ns的時間間隔表示 個100ns的CPU時間 個100ns的CPU時間GetProcesTimes返回的時間適用于某個進(jìn)程中的所有線程(甚至是已經(jīng)終止運(yùn)行的線程。Windows98遺憾的是,GetThreadTimes和GetProcessTimes這兩個函數(shù)在Windows98中不起作用。在Windows98中,沒有一個可靠的機(jī)制可供應(yīng)用程序來確定線程或進(jìn) tformSDK文檔中確實使人吃驚。不過如果“CONTEXT結(jié)構(gòu)包含了特定處理器的寄存器數(shù)據(jù)。系統(tǒng)使用CONTEXT結(jié)構(gòu)執(zhí)行各種內(nèi)部操作。目前,已經(jīng)存在為In、MIPS、Alpha和PowerPC處理器定義的CONTEXT結(jié)構(gòu)。若要Windows2000在哪個CPU上運(yùn)行。實際上,在WindowsCONTEXT結(jié)那么CONTEXT結(jié)構(gòu)中究竟存在哪些東西呢?它包含了主機(jī)CPU上的每個寄存器的數(shù)據(jù)結(jié)構(gòu)。在x86計算機(jī)上,數(shù)據(jù)成員是Eax、Ebx、Ecx、Edx等等。如果是Alpha成員包括IntV0、IntT0、IntT1、IntS0、IntRa和IntZero等等。下面這個代碼段顯示了x86的完整的CONTEXTCONTEXTCONTEXT_CONTROL包含CPU的控制寄存器,比如指令指針、堆棧指針、標(biāo)志和函數(shù)返回地址(與x86AlpyaCPU在調(diào)用函數(shù)時,將該函數(shù)的返回地址放入一個寄存器中。CONTEXT_INTEGER用于標(biāo)識CPU的整數(shù)寄存器。COTEXT_FLOATING_POIT用于標(biāo)識CP的浮點寄存器。CONTEXT_SEGMENTS用于標(biāo)識CPU的段寄存器(僅為x86處理器。CONTEXT_DEBUG_REGISTER用于標(biāo)識CPU的調(diào)試寄存器(僅為x86處理器。CONTEXT_EXTENDED_REGISTERS用于標(biāo)識CPU的擴(kuò)展寄存器Windows實際上允許查看線程內(nèi)核對象的內(nèi)部情況,以便抓取它當(dāng)前的一組CPU寄存器。進(jìn)行初始化,指明想要收回哪些寄存器,并將該結(jié)構(gòu)的地址傳遞給GetThreadContext。然后該在調(diào)用GetThreadContext函數(shù)之前,應(yīng)該調(diào)用SuspendThread,否則,線程可能被調(diào)度,而且線程的環(huán)境可能與你收回的不同。一個線程實際上有兩個環(huán)境。一個是用戶方式,一個是內(nèi)核方式。GetThreadContext只能返回線程的用戶方式環(huán)境。如果調(diào)用SuspendThread來停止線程的運(yùn)行,但是該線程目前正在用內(nèi)核方式運(yùn)行,那么,即使SuspendThread線程的運(yùn)行,它的用戶方式仍然處于穩(wěn)定狀態(tài)。線程在恢復(fù)用戶方式之前,它無法執(zhí)行的用戶方式代碼,因此可以放心地將線程視為處于暫停狀態(tài),GetThreadContext函數(shù)將能正常運(yùn)CONTEXT結(jié)構(gòu)的ContextFlag成員并不與任何CPU寄存器相對應(yīng)。無論是何種CPU結(jié)構(gòu),該成員存在于所有CONTEXT結(jié)構(gòu)定義中。ContextFlags成員用于向GetThreadContext注意,在調(diào)用GetThreadContext之前,首先必須對CONTEXT結(jié)構(gòu)中的ContextFlag成員進(jìn)ContexFlags初始化:下面是一些標(biāo)識符,使用這些標(biāo)識符可以獲得線程的所有重要的寄存器(即視為表7- CONTEXT_CONTROL|CONTEXT_INTEGER| CONTEXT_CONTROL|CONTEXT_FLOATING_POINT|當(dāng)GetThreadContext返回時,能夠很容易地查看線程的任何寄存器的值,但是要記住,這意味著必須編寫與CPU相關(guān)的代碼。表7-3根據(jù)CPU類型列出了CONTEXT結(jié)構(gòu)的指令指針和堆棧指針。表7-3CONTEXT
在調(diào)用SetThreadContext之前,必須再次對CONTEXT的ContextFlags成員進(jìn)行初始化,如下面的代碼所示:這有可能導(dǎo)致線程中的,向用戶顯示未處理的異常消息框,同時,進(jìn)程GetThreadContext和SetThreadContext函數(shù)使你能夠?qū)€程進(jìn)行許多方面的控制,但是在使用它們時應(yīng)該。實際上,幾乎沒有應(yīng)用程序調(diào)用這些函數(shù)。增加這些函數(shù)是為了增強(qiáng)調(diào)試程序和其他工具的功能。任何應(yīng)用程序都可以調(diào)用它們。本章開頭講述了CPU20ms,然后調(diào)度程序?qū)⒘硪粋€可調(diào)度的線程分配給CPU的。如果所有線程具有相同的優(yōu)先級,那么就會發(fā)生這種情況,但是,在現(xiàn)實環(huán)境中,線程被賦予許多不同的優(yōu)先級,這會影響到調(diào)度程序?qū)⒛膫€線程取出來作為下一個要運(yùn)每個線程都會被賦予一個從0(最低)到31(最高)的優(yōu)先級號碼。當(dāng)系統(tǒng)確定將哪個線程分配給CU時,它首先觀察優(yōu)先級為1的線程,并以循環(huán)方式對它們進(jìn)行調(diào)度。如果優(yōu)先級為31的線程可以調(diào)度,那么就將該線程賦予一個C。在該線程的時間片結(jié)束時,系統(tǒng)要查看31C。只要優(yōu)先級為31的線程是可調(diào)度的,系統(tǒng)就絕對不會將優(yōu)先級為0到30的線程分配給CPU。這種情況稱為渴求調(diào)度(starvation)。當(dāng)高優(yōu)先級線程使用大量的CPU時間,從而使得低優(yōu)先持繁忙狀態(tài),只有當(dāng)沒有線程可以調(diào)度的時候,CPU才處于空閑狀態(tài)。人們可能認(rèn)為,在這樣的系統(tǒng)中,低優(yōu)先級線程得不到機(jī)會運(yùn)行。不過正像前面的那樣,在任何一個時段內(nèi),系統(tǒng)中的大多數(shù)線程是不能調(diào)度的。例如,如果進(jìn)程的主線用GetMessage函數(shù),而系統(tǒng)發(fā)現(xiàn)沒有線程可以供它使用,那么系統(tǒng)就暫停進(jìn)程的線程運(yùn)行,釋放該線程的剩余時間片,并且立即將CPU分配給另一個等待運(yùn)行的線程。如果沒有為teae函數(shù)顯示可供檢索的消息,那么進(jìn)程的線程將保持暫停狀態(tài),并且決不會被分配給C。但是,當(dāng)消息被置于線程的隊列中時,系統(tǒng)就知道該線程不應(yīng)該再處于C?,F(xiàn)在考慮另一個問題。高優(yōu)先級線程將搶在低優(yōu)先級線程之前運(yùn)行,不管低優(yōu)先級線程正5的線程正在運(yùn)行,系統(tǒng)發(fā)現(xiàn)一個高優(yōu)先級的線程準(zhǔn)備要運(yùn)行,那么系統(tǒng)就會立即暫停低優(yōu)先級線程的運(yùn)行(即使它處于它的時間片中,并且將CPU分配給高優(yōu)先級線程,使它獲得一個完整的時間片。還有,當(dāng)系統(tǒng)引導(dǎo)時,它會創(chuàng)建一個特殊的線程,稱為0頁線程。該線程被賦予優(yōu)先級0,當(dāng)?shù)拈_發(fā)人員設(shè)計線度程序時,他們發(fā)現(xiàn)該調(diào)度程序無法在所有時間適應(yīng)所WindowsNT問世時,對象鏈接和嵌(OLE),OLE應(yīng)用程序已經(jīng)見慣。游戲軟件已經(jīng)相當(dāng)流行。當(dāng)然,在WindosT的早期,并沒有地考慮Internet的題。調(diào)度算法對用戶運(yùn)的應(yīng)用程序型有著相當(dāng)?shù)挠?。從一開始,的開發(fā)人員就認(rèn)識到,隨著系統(tǒng)的用途的變化,他們必須不斷修改調(diào)度算法。但是,軟件開發(fā)人員需要在今天編寫軟件,而則要保證軟件能夠在將來的系統(tǒng)版本上運(yùn)行。那么如何改WindowsAPI展示了系統(tǒng)的調(diào)度程序上的一個抽象層,這樣就不會直接與調(diào)度程序行通信。相反,要調(diào)用Wndos函數(shù),以便根據(jù)運(yùn)行的系統(tǒng)版本“轉(zhuǎn)換”參數(shù)。本章將介紹這然后,應(yīng)該根據(jù)你的應(yīng)用程序中的線程應(yīng)該具備何種響應(yīng)性,選擇一個優(yōu)先級類。這聽起來有些費(fèi)解,不過情況確實如此。不想出任何來可能影響你的代碼運(yùn)的承諾。indows支持6個優(yōu)先級類:即空閑、低于正常、正常、高于正常、高和實時。當(dāng)然,正99%的應(yīng)用程序均使用這個優(yōu)先級類。表7-4描述了這些優(yōu)先級類。表7-4Windows 描實時 進(jìn)程中的線程必須立即對作出響應(yīng)以便執(zhí)行關(guān)鍵時間的任務(wù)。該進(jìn)程中的線程還會搶先于操作系統(tǒng)組件之前運(yùn)行。使用本優(yōu)先級類時必須 TaskManager(任務(wù)管理器)在這個類上運(yùn)行,以便用戶可以撤消脫 進(jìn)程中的線程在正常優(yōu)先級與高優(yōu)先級之間運(yùn)行(這是Windows 當(dāng)系統(tǒng)什么也不做的時候,將空閑優(yōu)先級類用于應(yīng)用程序的運(yùn)行是最恰當(dāng)不過的。沒有用交互方式使用的計算機(jī)有可能仍然很繁忙(比如作為文件服務(wù)器,不應(yīng)該與屏幕保護(hù)程序爭用CPU時間。定期更新系統(tǒng)的某些狀態(tài)的統(tǒng)計信息應(yīng)用程序不應(yīng)該干擾關(guān)鍵任務(wù)的運(yùn)行。WindowsExplorer是在高優(yōu)先級上運(yùn)行的。大多數(shù)時間Explorer的線程是暫停的,等待用戶按下操作鍵或者點擊鼠標(biāo)按鈕時被喚醒。當(dāng)Explorer的線程處于暫停狀態(tài)時,系統(tǒng)不將它的線程分配給CPU。因為這將使低優(yōu)先級線程得以運(yùn)行。但是一旦用戶按下一個操作鍵或組合鍵,如Ctrl+Esc,系統(tǒng)就會喚醒Explorer的線程(當(dāng)用戶按下Ctrl+Esc組合鍵時,也會出現(xiàn)Start菜單。如果低優(yōu)先級線程正在運(yùn)行,系統(tǒng)會立即搶在這些線程的前面,讓Explorer就是按這種方法設(shè)計Explorer的,因為用戶希望無論系統(tǒng)中正在運(yùn)行什么,外殼程序都具有極強(qiáng)的響應(yīng)能力。實際上,即使低優(yōu)先級線程在無限循環(huán)中暫停運(yùn)行,也能顯示Explorer的窗口。由于Explorer的線程擁有較高的優(yōu)先級,因此執(zhí)行無限循環(huán)的線程被搶占,Explorer讓用戶終止掛起進(jìn)程的運(yùn)行。Explorer可做,不必占用CP時間。如果情況不是如此,那么整個系統(tǒng)的運(yùn)行速度就會慢得多,許多應(yīng)用程序就不會作出響應(yīng)。應(yīng)該盡可能避免使用實時優(yōu)先級類。實際上WindowsNT3.1序展示這個優(yōu)先級類,盡管該操作系統(tǒng)支持這個類。實時優(yōu)先級是很高的優(yōu)先級,它可能干擾操作系統(tǒng)任務(wù)的運(yùn)行,因為大多數(shù)操作系統(tǒng)線程均以較低的優(yōu)先級來運(yùn)行。因此實時線程可能必要的磁盤I/O信息和網(wǎng)絡(luò)信息的產(chǎn)生。此外,鍵盤和鼠標(biāo)輸入將無法及時得到處理,用戶可能以為系統(tǒng)已經(jīng)暫停運(yùn)行。大體來說,必須有足夠的理由才能使用實時優(yōu)先級,比如需要以很短的等待時間來響應(yīng)硬件,或者執(zhí)行某些不能中斷的短期任務(wù)。注 當(dāng)然,大多數(shù)進(jìn)程都屬于正常優(yōu)先級類。低于正常和高于正常的優(yōu)先級類是Windos2000中的新增優(yōu)先級。增加這些優(yōu)先級類的原因是,有若干家公司抱怨現(xiàn)有的優(yōu)先級類無一旦選定了優(yōu)先級類之后,就不必考慮你的應(yīng)用程序與其他應(yīng)用程序之間的關(guān)系,只需要集中考慮你的應(yīng)用程序中的各個線程。Windows支持7個相對的線程優(yōu)先級:即空閑、最低、低于正常、正常、高于正常、最高和關(guān)鍵時間優(yōu)先級。這些優(yōu)先級是相對于進(jìn)程的優(yōu)先級類而言的。大多數(shù)線程都使用正常線程優(yōu)先級。表7-5描述了這些相對的線程優(yōu)先級。表7-5 類來說,線程在優(yōu)先級1上運(yùn)行概括起來說,進(jìn)程是優(yōu)先級類的一個組成部分,你為進(jìn)程中的線程賦予相對線程優(yōu)先級。這里沒有講到到3的優(yōu)先級的任何情況。應(yīng)用程序開發(fā)人員從來不必具體設(shè)置優(yōu)先級。相反,系統(tǒng)負(fù)責(zé)將進(jìn)程的優(yōu)先級類和線程的相對優(yōu)先級映射到一個優(yōu)先級上。正是這種映射方式,不想拘泥不變。實際上這種映射方式是隨著系統(tǒng)的版本的升級而變化的。表7-6顯示了這種映射方式是如何用于Windows2000的,注意,WindowsNT的早期版本和某些Windows95和Windows98版本采用了不同的映射方式。未來的Windows版本中的映射方式例如,正常進(jìn)程中的正常線程被賦予的優(yōu)先級是8。由于大多數(shù)進(jìn)程屬于正常優(yōu)先級類,而大多數(shù)線程屬于正常線程優(yōu)先級,因此系統(tǒng)中的大多數(shù)線程的優(yōu)先級是8。13為8,那么線程的優(yōu)先級就變?yōu)?。如果改變了進(jìn)程的優(yōu)先級類,線程的相對優(yōu)先級不變,但是表7-6優(yōu)先級高684683579246811111注意,表7-6并沒有顯示優(yōu)先級的等級為0的線程。這是因為0優(yōu)先級保留供零頁線程使用,017、18、19、202127282930。如果編寫一個以內(nèi)核方式運(yùn)行的設(shè)備驅(qū)動程序,可以獲得這些優(yōu)先級等級,而用戶方式的應(yīng)用程序則不能。另外還要注意,實時優(yōu)先級類中的線程不能低于優(yōu)先級等級1615。注意有些人常常搞不清進(jìn)程優(yōu)先級類的概念。他們認(rèn)為這可能意味著進(jìn)程是可以調(diào)度的。但是進(jìn)程是根本不能調(diào)度的,只有線程才能被調(diào)度。進(jìn)程優(yōu)先級類是個抽象概念,提出這個概念的目的,是為了幫助你將它與調(diào)度程序的內(nèi)部運(yùn)行情況區(qū)分開來。它沒有其他目的。注意一般來說,大多數(shù)時候高優(yōu)先級的線程不應(yīng)該處于可調(diào)度狀態(tài)。當(dāng)線程要進(jìn)行某種操作時,它能迅速獲得CPU時間。這時線程應(yīng)該盡可能少地執(zhí)行CPU指令,并返執(zhí)行大量的CPU指令來進(jìn)行它的操作。如果按照這些原則來辦,整個操作系統(tǒng)就能正確地對用戶作出響應(yīng)。表7-7 標(biāo)識 創(chuàng)建子進(jìn)程的進(jìn)程負(fù)責(zé)選擇子進(jìn)程運(yùn)行的優(yōu)先級類,這看起來有點奇怪。讓我們以Explorer為例來說明這個問題。當(dāng)使用Explorer行。Explorer不知道進(jìn)程在做什么,也不知道隔多長時間它的線程需要進(jìn)行調(diào)度。但是,一旦子進(jìn)程運(yùn)行,它就能夠通過調(diào)用SetPriorityClas該函數(shù)將hProces標(biāo)識的優(yōu)先級類改為fdwPriority參數(shù)中設(shè)定的值。fdwPriority參數(shù)可以是表7-7顯示的標(biāo)識符之一。由于該函數(shù)帶有一個進(jìn)程句柄,因此,只要擁有該進(jìn)程的句柄和足夠的權(quán),就能夠改變系統(tǒng)中運(yùn)行的任何進(jìn)程的優(yōu)先級類。當(dāng)使用命令外殼啟動一個程序時,該程序的起始優(yōu)先級是正常優(yōu)先級。但是,如果使用Start命令來啟動該程序,可以使用一個開關(guān)來設(shè)定應(yīng)用程序的起始優(yōu)先級。例如,在命令外殼輸入下面 令可使系統(tǒng)啟動Calculator,并在開時空閑優(yōu)先級來運(yùn)行它:StartBELOWNORMAL、NORMAL、ABOVENORMAL、HIGH/REALTIME等開關(guān),以便按它們各自的優(yōu)先級啟動執(zhí)行一個應(yīng)用程序。當(dāng)然,一旦應(yīng)用程序啟動運(yùn)行,它就可以調(diào)用SetPriorityClasWindows Windows98的Start命令并不支持這些開關(guān)中的任何一個。WindowsWindows2000的TaskManager使得用戶可以改變進(jìn)程的優(yōu)先級類。圖72顯示了Manager的Processes選項卡,它顯示了當(dāng)前運(yùn)行的所有進(jìn)程。BasePri級類??梢愿淖冞M(jìn)程的優(yōu)先級類,方法是選定一個進(jìn)程,然后從上下文菜單的SetPriority(設(shè)圖7-2WindowsTaskManagerCreateThread沒有為調(diào)用者提供一個設(shè)置新線程的相對優(yōu)先級的方法。若要設(shè)置和獲得線程的相對優(yōu)先級,必須調(diào)用下面的這些函數(shù):表7-8 注意,CreateThread函數(shù)創(chuàng)建的新函數(shù)帶有的相對優(yōu)先級總是正常優(yōu)先級。若要使線程以空閑優(yōu)先級來運(yùn)行,應(yīng)該將CRETE_SUSPENDED標(biāo)志傳遞給CreateThread函數(shù),這可以防止SetThreadPriority,將線程的優(yōu)先級改為相對空閑優(yōu)先級。這時可以調(diào)用ResumeThread,使得線程成為可調(diào)度的線程。你不知道線程何時能夠獲得CP時間,但是調(diào)度程序會考慮這樣一個情況,即該線程擁有一個空閑優(yōu)先級。最后,可以關(guān)閉新線程的句柄,一旦線程終止運(yùn)行,內(nèi)核對象就能被撤消。 Windows沒有提供返回線程的優(yōu)先級的函數(shù)。這是故意進(jìn)行的。記住,保留了隨時修改調(diào)度算法的權(quán)利。你不會設(shè)計需要調(diào)度算法專門知識的應(yīng)程序。如果堅持使用進(jìn)程優(yōu)先級類和相對線程優(yōu)先級,你的應(yīng)用程序不僅現(xiàn)在能夠順通過將線程的相對優(yōu)先級與線程的進(jìn)程優(yōu)先級類綜合起來考慮,系統(tǒng)就可以確定線程的優(yōu)先級等級。有時這稱為線程的基本優(yōu)先級等級。系統(tǒng)常常要提高線程的優(yōu)先級等級,以便對窗口消息或磁盤等I/O作出響應(yīng)。例如,在高優(yōu)先級類進(jìn)程中的一個正常優(yōu)先級等級的線程的基本優(yōu)先級等級是13。如果用戶按下一個操作鍵,系統(tǒng)就會將一個WM_KEYDOWN消息放入線程的隊列中。由于一個消息已經(jīng)出現(xiàn)程的隊列中,因此該線程就是可調(diào)度的線程。此外,鍵盤設(shè)備驅(qū)動程序也能夠訴系統(tǒng)暫時提高線程的優(yōu)先級等級。該線程的優(yōu)先級等級可能提高2級,其當(dāng)前優(yōu)先級等級改系統(tǒng)在優(yōu)先級為5時為一個時間片對該線程進(jìn)行調(diào)度。一旦該時間片結(jié)束,系統(tǒng)便將線程的優(yōu)先級遞減1,使下一個時間片的線程優(yōu)先級降為14。該線程的第三個時間片按優(yōu)先級等級13行線執(zhí)的,本等級1來執(zhí)。注意,線程的當(dāng)前優(yōu)先級等級決不會低于線程的基本優(yōu)先級等級。此外,導(dǎo)致線程成為可調(diào)度程設(shè)備動序以決優(yōu)級級提的量。并沒有規(guī)定各個設(shè)備驅(qū)動程序可以給線程的優(yōu)先級提高多少個等級。這樣就使得可以不斷地調(diào)整線程優(yōu)先級提高的動態(tài)等級,以確定最佳的總體響應(yīng)性能。1至15之間的線程提高其優(yōu)先級等級。實際上這是因為這個(15由于實時范圍中的線程能夠執(zhí)行大多數(shù)操作系統(tǒng)的函數(shù),因此給等級的提高規(guī)定一個范圍,就可以防止應(yīng)用程序干擾操作系統(tǒng)的運(yùn)行。另外,系統(tǒng)決不會動態(tài)提高實時范圍內(nèi)的線程優(yōu)先級等級。有些編程人員抱怨說,系統(tǒng)動態(tài)提高線程優(yōu)先級等級的功能對他們的線程性能會產(chǎn)生一種不良的影響,為此增加了下面兩個函數(shù),這樣就能夠使系統(tǒng)的動態(tài)提高線程優(yōu)先級等級的功能不起作用:SetProcessPriorityBoost負(fù)責(zé)告訴系統(tǒng)激活或停用進(jìn)行中的所有線程的優(yōu)先級提高功能,而SetThreadPriorityBoost則讓你激活或停用各個線程的優(yōu)先級提高功能。這兩個函數(shù)具有許多相似的共性,可以用來確定是激活還是停用優(yōu)先級提高功能:Windows Windows98沒有提供這4另一種情況也會導(dǎo)致系統(tǒng)動態(tài)地提高線程的優(yōu)先級等級。比一個優(yōu)先級為4的線程準(zhǔn)84的線程就非??释玫紺PU時間。當(dāng)系統(tǒng)發(fā)現(xiàn)一個線程在大約3至4內(nèi)一直渴望得到CPU時間,它就將這個渴望得到CPU時間的線程的優(yōu)先級動態(tài)提高到15,并讓該線程運(yùn)行兩倍于它的時間Winos能夠為前臺進(jìn)程中的線整其調(diào)度算法。對于Wndos000來說,系統(tǒng)可以為前臺進(jìn)程的線程提供比通常多的CU時間量。這種調(diào)整只能臺進(jìn)程屬于正常優(yōu)先級類的進(jìn)程時Windows2000實際上允許用戶對這種調(diào)整進(jìn)行相應(yīng)的配置。在SystemProperties(系統(tǒng)屬性)框的Advanced選項卡上,用戶可以單擊PerformanceOptions(性能選項)按鈕,打開圖圖7-3PerformanceOptions如果用戶選擇優(yōu)化應(yīng)用程序的性能,系統(tǒng)就執(zhí)行配置的調(diào)整。如果用戶選擇優(yōu)化服務(wù)程序的性能,系統(tǒng)就不進(jìn)行調(diào)整。當(dāng)安裝Windows2000的專業(yè)版時,Applications就會被默認(rèn)選定。對于Windows2000的所有其他版本,則默認(rèn)選定BackgroundServices,因為計算機(jī)將主,Windows98也會對正常優(yōu)先級類的進(jìn)程中的線度算法進(jìn)行調(diào)整。當(dāng)一個優(yōu)先級為正常的進(jìn)程移到前臺時,系統(tǒng)便將最低、低于正常、正常、高于正常和最高等1,優(yōu)先級為空閑和關(guān)鍵時間的線程的優(yōu)先級則不予提高。因此,9而不是8。當(dāng)進(jìn)程返回時,進(jìn)中的線程便自動回它們定好的基本優(yōu)先級等級。Windows98 Windows98沒有提供允許用戶配置這種調(diào)整的任何用戶界面,因為Windows98不是作為服務(wù)器來運(yùn)行的。將進(jìn)程改為前臺進(jìn)程的原因是,使它們能夠?qū)τ脩舻妮斎敫斓刈鞒鲰憫?yīng)。如果不改為前臺進(jìn)程,那么在的正常打印進(jìn)程與在接收用輸入的正常進(jìn)程就會地爭用CPU時間。用戶會發(fā)現(xiàn)文本無法臺應(yīng)用程序中順利地顯示。但是,由于系統(tǒng)改變了前臺進(jìn)程的線使用SchedulingLab應(yīng)程序“07SchedLab.exe見后面的7-1,可以對進(jìn)程優(yōu)先級類和相對線程優(yōu)先級進(jìn)行操作試驗,以了解它們對系統(tǒng)的總體性能產(chǎn)生的影響。該應(yīng)用程序的07-SchedLab7-4開始時,主線程總是處于繁忙狀態(tài),因此CPU的使用量立即跳到100%。該主線程連續(xù)遞Manager,以便所有實例的CPU使用量。相等的CPU時間(TaskManager應(yīng)該顯示應(yīng)用程序的所有實例大致相同的CPU使用量百分比。CPU使用量。而其他實例中的數(shù)字滾動則沒有規(guī)律。但是其他實例的數(shù)字不會完全停止?jié)L動,因為系統(tǒng)將為渴求CP時間的線程自動執(zhí)行優(yōu)先級的動態(tài)提高。不管怎樣,可以隨意調(diào)整優(yōu)先SchedulingLab應(yīng)用程序進(jìn)行了編碼,這樣就無法將進(jìn)程改為實時優(yōu)先級類,這可以防止操作系統(tǒng)線程的不正常的運(yùn)行。如果想要試用實時優(yōu)先級,必須自己修改源代碼??梢允褂胑ep域,使主線0到999之間的任意毫秒內(nèi)無法調(diào)度。請試用這項功能,并觀察傳遞僅為ms的睡眠值時可以重新獲得多少C時間。在我的30zetimI筆記本電腦上,我贏得了9%的C單擊Suspend(暫停)按鈕,可使主線程產(chǎn)生一個子線程。這個子線程能夠暫停主線程的運(yùn)行,并顯示圖7-5圖7-5當(dāng)這個息框顯時,線完全暫運(yùn)行并且使用任何CPU時間。子線程也不用任何CP時間,因為它是在等待用戶執(zhí)行某種操作。當(dāng)消息框顯示時,可以將它移到應(yīng)用程序的主窗口,然后將它移開,這樣就能夠看到主窗口。由于主線程已經(jīng)暫停運(yùn)行,因此主窗口將無法接收任何窗口消息(包括WM_PAINT。這證明該線程已經(jīng)暫停運(yùn)行。當(dāng)關(guān)閉該消息框,CP使用量回到100%。要一,前紹的PerformanceOptions框,將Application改為BackgroundServices,或者將Backgroundervices改為Application。然后打開SchedLab程序的多個實例,將它們?nèi)吭O(shè)置為正常優(yōu)先級類,并激活其中的一個,使之成為一個前臺進(jìn)程。這時就能夠看到性能的設(shè)置對前臺/進(jìn)程產(chǎn)生的影響。7-1SchedLabWindows2000使用軟親緣性來進(jìn)行操作。這意味著如果所有其他因素相同的話,它將設(shè)法在它上次運(yùn)行的那個處理器上運(yùn)行線程。讓線程留在單個處理器上,有助于重復(fù)使用仍然在處理器的內(nèi)存高速緩存中的數(shù)據(jù)。有一種新的計算機(jī)結(jié)構(gòu),稱為(非統(tǒng)一內(nèi)存),在該結(jié)構(gòu)中,計算機(jī)包含若干塊插件板,每個插件板上有4個C7-6顯示了一臺配有3塊插件板的計算機(jī),總共有2個C12個C 圖7-6NUMA當(dāng)CPU,NUMA系統(tǒng)運(yùn)行的性能最好。如果CPU需要位于另一個插件板上的內(nèi)存時,性能就會大大降低。在這樣的環(huán)境中,就需要來自一個進(jìn)程中的線CPU0至3上運(yùn),另個的CPU4至7上運(yùn)行,依次類推。Windos2000允許設(shè)置進(jìn)程和線程的親緣性。換句話說,可以控制哪個CPU能夠運(yùn)行某些線程。這稱為硬親緣性。第一個參數(shù)hProcess用于指明要影響的是哪個進(jìn)程。第二個參數(shù)dwProcessAffinityMask是 可以在CPU0和CPU2上運(yùn)行,但是不能在CPU1和CPU3至31上運(yùn)行。注意,子進(jìn)程可以繼承進(jìn)程的親緣性。因此,如果一個進(jìn)程的親緣性是0x 那么它的子進(jìn)程中的任何線程都擁有相同的位,并共享相同的CPU。此外,可以使用作業(yè)這里也可以傳遞想要親緣性的進(jìn)程句柄,該函數(shù)填入pdwProcessAffinityMask指向變量。該函數(shù)還能返回系統(tǒng)的親緣性(在pdwSystemAffinityMask指向的變量中。系統(tǒng)的親緣性用于指明系統(tǒng)的哪個CPU能夠處理線程。進(jìn)程的親緣性始終是一個系統(tǒng)的親緣Windows98 無論計算機(jī)中實際擁有多少個CPU,Windows98只使用一個CPU。因CPU上去運(yùn)行。有時可能想要CPU4個線程的進(jìn)程,它們在擁有4個CPU的計算機(jī)上運(yùn)行。如果這些線程中的一個線程正在執(zhí)行非常重要的操作,而你想增加某個CPU3個線程進(jìn)行了限制,使它們不能在CPU0上運(yùn)行,而只能在PU1、2和3上運(yùn)行。該函數(shù)中的hThreaddThreadAffinityMask用于指明該線程能
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 湖北省恩施市2025-2026學(xué)年上學(xué)期期末八年級數(shù)學(xué)試卷(無答案)
- 廣東省東莞市常平鎮(zhèn)2025-2026學(xué)年九年級上學(xué)期1月期末歷史試卷(含答案)
- 五年級測試卷及答案
- 文員考試試題及答案
- 《遇見未知的自我》讀后感范本
- 2022-2023學(xué)年山東省東營市墾利區(qū)九年級物理第一學(xué)期期末調(diào)研試題含解析
- 2022屆高考數(shù)學(xué)基礎(chǔ)總復(fù)習(xí)提升之專題突破詳解專題10三角函數(shù)的圖象與性質(zhì)含解析
- 六盤水中考滿分作文賞析:書給了我力量
- 22春“安全工程”專業(yè)《安全檢測及儀表》在線作業(yè)含答案參考2
- 師德以身作則演講稿
- 要素式民事起訴狀(房屋租賃合同糾紛)
- 急性呼吸窘迫綜合征病例討論
- GB/T 43590.507-2025激光顯示器件第5-7部分:激光掃描顯示在散斑影響下的圖像質(zhì)量測試方法
- QGDW12505-2025電化學(xué)儲能電站安全風(fēng)險評估規(guī)范
- 2024年山東濟(jì)南中考滿分作文《為了這份繁華》
- 2025年鐵嶺衛(wèi)生職業(yè)學(xué)院單招職業(yè)傾向性測試題庫新版
- 2025年常州機(jī)電職業(yè)技術(shù)學(xué)院高職單招語文2018-2024歷年參考題庫頻考點含答案解析
- 民間融資居間合同
- 環(huán)境污染損害評估報告
- 表面活性劑化學(xué)知識點
- 《塑料材質(zhì)食品相關(guān)產(chǎn)品質(zhì)量安全風(fēng)險管控清單》
評論
0/150
提交評論