Windows CE.NET是一個搶占多任務操作系統,搶占多任務又被稱為調度。在調度過程中,內核的調度系統包含一個當前所有進程中線程的優先級列表,并對所有的線程按優先級排列順序。當中斷發生時,調度系統重新安排所有線程的排列順序。
一個進程是一個正運行的應用程序的實例。它由兩個部分組成:一個是操作系統用來治理這個進程的內核對象。另一個是這個進程擁有的地址空間。這個地址空間包含應用程序的代碼段、靜態數據段、堆、棧,非Xip(Execute In Place)DLL。從執行角度方面看,一個進程由一個或多個線程組成。一個線程是一個執行單元,它控制CPU執行進程中某一段代碼段。一個線程可以訪問這個進程中所有的地址空間和資源。一個進程最少包括一個線程來執行代碼,這個線程又叫做主線程。
2、進程:
Windows CE.NET最多支持32個進程同時運行。這是由整個系統分配給所有進程的總地址空間決定的。低于Windows CE 4.0版本(也就是低于.NET的版本)的CE操作系統,總進程空間從0x0000 0000到0x4200 0000 ,每32MB地址空間為一個槽(Slot),共33個槽。當一個進程啟動時,內核選擇一個沒有被占用的槽作為這個進程的地址空間。其中0x0000 0000到0x01FF FFFF這個槽稱為Slot 0。每個進程在即將得到CPU控制權時,將整個地址映射到Slot 0。這個進程在幫助文檔中稱為當前運行進程(currently running PRocess)。分配一個槽后,內核在這個槽內按由低地址到高地址順序為代碼段、靜態數據段分配足夠的地址空間,然后是堆、棧,棧之后的空間為所有 DLL保留,包括XIP和非XIP DLL。注重Slot 0最底部64KB是永遠保留的。從Slot 1 到 Slot32 為進程使用。前幾個槽一般為系統程序使用。如filesys.exe、device.exe、gwes.exe等。
Windows CE.NET不像其他Windows操作系統將進程分為不同的優先級類,Windows CE.NET只將線程分為256個優先級。0優先級最高,255最低,0到248優先級屬于實時性優先級。0到247優先級一般分配給實時性應用程序、驅動程序、系統程序。249到255優先級中,251優先級(THREAD_PRIORITY_NORMAL)是正常優先級。255優先級(THREAD_PRIORITY_IDLE)為空閑優先級。249優先級(THREAD_PRIORITY_HIGHEST)是高優先級。248到255優先級一般分配給普通應用程序線程使用。具體分段見下表:
優先級范圍分配對象 0-96高于驅動程序的程序 97-152 基于Windows CE的驅動程序 153-247低于驅動程序的程序 248-255 普通的應用程序 Windows CE.NET操作系統具有實時性,所以調度系統必須保證高優先級線程先運行,低優先級線程在高優先級線程終止后或者阻塞時才能得到CPU時間片。而且一旦發生中斷,內核會暫停低優先級線程的運行,讓高優先級線程繼續運行,直到終止或者阻塞。具有相同優先級的線程平均占有CPU時間片,當一個線程使用完了CPU時間片或在時間片內阻塞、睡眠,那么其他相同優先級的線程會占有時間片。這里提到的CPU時間片是指內核限制線程占有CPU的時間,默認為100ms。OEM可以更改這個值,甚至設置為0。假如為0,當前線程將一直占有CPU,直到更高優先級線程要求占有CPU。這個調度算法似乎是很有效、很完美,但卻存在著一種情況,當這種情況發生時程序會死鎖。舉例來說:一個應用程序包含兩個線程,線程1是高優先級,線程2是低優先級,當線程1運行過程中處于阻塞時,線程2得到時間片,線程2這次進入了一個臨界區,我們都知道臨界區內的資源是不會被其它線程訪問的,當線程2正運行時,線程1已經從阻塞狀態轉變為運行狀態,而這次線程1卻要訪問線程2的資源,這個資源卻被臨界區鎖定,那么線程1只能等待,等待線程2從臨界區中運行結束并釋放資源的獨占權。但是線程2卻永遠不會得到時間片,因為CE保證高優先級線程會先運行。這時程序就會處于死鎖狀態。當然系統不會死鎖,因為還有更高優先級的線程、驅動程序在運行。對于這種情況,CE采取優先級轉換的辦法來解決。就是當發生這種情況時,內核將線程2的優先級提高到線程1的優先級水平。這樣線程2就可以執行完臨界區代碼了,線程1也就能夠訪問資源了。然后內核再恢復線程2原來的優先級。