|
如何從零基礎(chǔ)學(xué)嵌入式_英創(chuàng)信息技術(shù)應(yīng)用線程時(shí)間片分析比較介紹,
對(duì)于一個(gè)嵌入式多任務(wù)、多線程操作系統(tǒng),所啟動(dòng)的應(yīng)用進(jìn)程至少擁有一個(gè)線程或多個(gè)線程,線程在進(jìn)程中執(zhí)行代碼。一個(gè)進(jìn)程能夠“同時(shí)”運(yùn)行多個(gè)線程,“同時(shí)”加上引號(hào),因?yàn)閷?shí)際上,在單處理CPU平臺(tái)上,任何時(shí)刻,只有一個(gè)線程在執(zhí)行。操作系統(tǒng)通過(guò)任務(wù)調(diào)度算法快速切換線程來(lái)模擬多線程并行,交替地停止一個(gè)線程,然后切換到另外一個(gè)上運(yùn)行。支持任務(wù)優(yōu)先級(jí),高優(yōu)先級(jí)線程比低優(yōu)先級(jí)線程更先執(zhí)行,也就是說(shuō)低優(yōu)先線程必須等到高優(yōu)先級(jí)線程被阻塞掛起后才可能被調(diào)度。對(duì)于優(yōu)先級(jí)別相等的線程使用輪換算法來(lái)調(diào)度。
無(wú)論是WinCE還是Linux操作系統(tǒng),應(yīng)用線程的運(yùn)行總是涉及到兩個(gè)基本的參數(shù):一個(gè)是系統(tǒng)分配給線程的時(shí)間片,一個(gè)是系統(tǒng)調(diào)度的時(shí)間間隔。Linux和WinCE下這兩個(gè)參數(shù)有所不同,如下表所示:
|
WinCE |
嵌入式Linux | 線程的運(yùn)行時(shí)間片 |
100ms |
10ms | 系統(tǒng)調(diào)度間隔 |
1ms |
10ms |
這里需要注意的是,線程不一定需要將時(shí)間片完全用完,事實(shí)上,在嵌入式系統(tǒng)中,線程的運(yùn)行處理時(shí)間通常都遠(yuǎn)小于所分的時(shí)間片,這時(shí)線程應(yīng)當(dāng)調(diào)用相關(guān)系統(tǒng)函數(shù)將自己掛起,系統(tǒng)將立即進(jìn)行線程重調(diào)度。這時(shí)的重調(diào)度實(shí)際是加快了各個(gè)線程的輪片,提高了多線程并行運(yùn)行的程度,客觀上保證了嵌入式設(shè)備的實(shí)時(shí)響應(yīng)能力。
如果線程運(yùn)行處理的時(shí)間超過(guò)了系統(tǒng)分配的時(shí)間片,在到達(dá)時(shí)間片后系統(tǒng)將強(qiáng)制掛起該線程,進(jìn)行任務(wù)調(diào)度,以保證其他線程的運(yùn)行。所以在多任務(wù)的程序設(shè)計(jì)中,特別忌諱線程中出現(xiàn)長(zhǎng)時(shí)間查詢代碼,如:
while( bFlag == FALSE )
{
// Polling Flag…
}
這種代碼總是占完了時(shí)間片,大大地浪費(fèi)CPU資源,使得整個(gè)進(jìn)程的線程調(diào)度變得很慢,比如對(duì)于WinCE來(lái)說(shuō),就會(huì)出現(xiàn)100ms才調(diào)度一次,如果有10個(gè)這樣的線程,意味著每個(gè)線程需要1s才能輪詢一次,在嵌入式應(yīng)用中,就很容易出現(xiàn)數(shù)據(jù)丟失等錯(cuò)誤,從而無(wú)法實(shí)現(xiàn)正常的功能。對(duì)于Linux也是存在同樣的問題。
在實(shí)際應(yīng)用中,常用的掛起線程的方法是調(diào)用延時(shí)函數(shù)。對(duì)于WinCE,調(diào)用Sleep( ms )函數(shù);對(duì)Linux,可以調(diào)用select( )函數(shù)來(lái)掛起當(dāng)前線程。由于系統(tǒng)的調(diào)度間隔不一樣,對(duì)相同的掛起時(shí)間,系統(tǒng)會(huì)有不同的處理。比如,設(shè)置掛起時(shí)間為2ms,在WinCE中,將在掛起2ms之后的1ms后,被系統(tǒng)重新調(diào)度;在Linux中,由于調(diào)度間隔大于掛起的時(shí)間,所以系統(tǒng)將在線程掛起10ms之后才被重新調(diào)度,也就是說(shuō)在Linux下,無(wú)論程序中設(shè)置的掛起時(shí)間2ms還是9ms,該線程實(shí)際被掛起的時(shí)間總是10ms。 |
|