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