ucos操作系统的内核有哪些调度方法
1)時間片輪番調度法
假設系統中有5個任務,T1,T2,T3,T4,T5,這個時候,操作系統為每一個任務分配時間,比如說我們為T1任務分配10毫秒,為T2任務分配20毫秒,為T3任務分配5毫秒,為T4任務分配10毫秒,為T5任務分配10毫秒,系統啟動以后,首先分配第一個任務10毫秒,第一個任務運行10毫秒以后,操作系統把第一個任務停止掉,開始運行第二個任務,第二個任務運行20毫秒以后,操作系統把第二個任務停止掉,然后運行第三個任務,這是個時間片輪番法,當然在這里會出現一個問題,什么問題呢?
假設運行了5毫秒以后,T1這個任務已經不再運行了,比如現在休眠了,出現了一個等待延時,那就是說我不在運行了,那這樣的情況下,剩下的5毫秒怎么辦呢?操作系統怎么處理呢?是這樣的,剩下的5毫秒操作系統會直接運行T2,也就是說,在這個時間片輪番調度法中,操作系統進行任務切換有兩種可能,第一種是這個任務主動放棄CPU,就像這種,運行了5毫秒不需要運行了,第二種就是被動放棄,運行10毫秒的時間到了,你必須停止下來,這就是被動放棄CPU。我們可以看到時間片輪番調度法是比較方便的,比較簡單的調度方法.
2)優先級調度法
3)它和時間片輪番調度法有個最本質的區別,它總是保證優先級最高的任務最先執行。假設系統中還是有5個任務,T1,T2,T3,T4,T5,這個時候,我為每一個任務分配一個優先級,假設他們的優先級分別是0,1,2,3,4,在這里我們規定,數字越小,優先級越高,那么也就是T1這個任務優先級是最高的,那操作系統運行以后就開始運行T1這個任務,T1這個任務在運行過程中,什么時候會運行第二個任務呢?
由于T1它的任務比較高,所以會一直運行這個任務,那這個時候問題來了,如果一直運行T1這個任務,那T2這個任務是沒辦法運行的,,所以這個優先級調度方法你必須保證T1這個任務要主動放棄CPU,這個時候,你才能運行T2,如果T1這個任務不主動放棄CPU,那么T2是不能運行的,所以,在這里我們要注意。哪些是主動放棄CPU呢?
比如我們現在要等待一個東西,或者要進行一個延時狀態,也就是我休息10毫秒,休息后我再進行,那這樣的方法都被視為放棄CPU,動放棄CPU后接下來就運行T2,假設在T2的運行過程中,運行到某個階段,T2還沒有運行完,這個時候,T1已經延時的時間到了,比如休息10毫秒后,我的時間到了,那接下來怎么辦呢?
這個時候優先級調度就會打斷T2,把T2終止掉,然后再運行T1,因為T1的優先級高啊,我現在延時時間到了,那我就要現在運行了,那這個時候就進入T1,那T1在運行的過程中,只要主動放棄CPU,那就接著T2往下運行,那么T2在運行過程中,它主動放棄CPU,那我們就運行T3。同樣的道理,在T3運行的過程中,只要有T1或者T2它們兩個中任何要運行,CPU都會強制停止T3,來運行T1或者T2,這就是一個優先級的調度辦法。從這我們可以看出優先級調度法和時間片輪番調度法有個最本質的區別,就是優先級,時間片輪番調度法是沒有優先級的,而優先級調度法就是說每個任務必須有一個優先級。實際上,在我們現在的操作系統中,有的是使用時間片輪番調度法,比如說我們的linux操作系統,或者windows操作系統,而我們的ucos2它是使用的優先級調度法。有些時候它可能是結合了優先級調度法和時間片輪番調度法這兩個方法,那這個是什么意思呢?
其實假設系統中還是有5個任務,T1,T2,T3,T4,T5,這個時候這5個任務開始分配優先級,我們剛剛分配的是0,1,2,3,4,也就是說,這5個任務必須對應一個優先級,這個任務的優先級是不允許相同的,那接下來我規定這個任務的優先級是允許相同的,比如T1和T2我都分配任務的優先級為0,T3,T4,都分配為1,T5分配為2,那這個時候我們來看,T1和T2的優先級是相同的,那操作系統啟動以后,是先允許T1還是T2呢?
它是這樣的,當兩個任務的優先級相同以后,那就需要為這兩個任務指定一個運行時間,比如T1是5毫秒,T2是10毫秒,那這個時候,當T1要執行的時候,T1首先運行5毫秒,5毫秒時間到了以后,接下來運行T2是10毫秒,運行完以后,接下來在運行T1,假設T1運行5毫秒以后,它開始進行休眠狀態,也就是延時等待,T2運行10毫秒,它也延時等待,那這個時候,才有可能運行T3,T4,這個就是把優先級調度法和時間片輪番調度法進行了結合,我們可以看出,這個的調度方法,結合了優先級調度法和時間片輪番調度法的好處,把它們的好處都給繼承了。
?
在優先級調度法中,還有兩種辦法,一個是不可剝奪性內核,一個是可剝奪性內核。
不可剝奪性內核
就是在運行的過程中,這個內核,不可以被剝奪。
它和我們的輪番調度法有一點比較相似,假設系統中還是有5個任務,T1,T2,T3,T4,T5,這個時候,這5個任務開始分配優先級,0,1,2,3,4,假設第1個任務由T1執行,如果是一個不可剝奪性內核,那這個任務是永遠不可能被剝奪的,除非它主動放棄CPU,當它主動放棄CPU以后,第2個任務才開始執行,這個時候,我們會發現一個特點,什么特點?
第2個任務在執行的過程中,執行到某個地方,第1個任務要執行,那這個時候,如果是一個不可剝奪性內核,那么就算你第2個任務要執行,由于這個時候,第2個任務還沒有執行完畢,那這個時候第1個任務還是不能執行,你只有等到第2個任務運行完畢后,你才可以執行,這就是不可剝奪性內核。我們再來看第二個例子:假設先開始運行的是T2,假設系統中還是有5個任務,T1,T2,T3,T4,T5,這個時候,這5個任務開始分配優先級,0,1,2,3,4,假設T2運行到了某個地方,T3就說我要運行,但是T3由于沒有T2的優先級高,所以說T2是不會讓它運行,T2會接著往下運行,接著往下運行以后,假設到了某個地方,T1說我要運行,但是由于我們使用的是不可剝奪性內核,那么T2還沒有運行完畢,還沒有主動放棄CPU,那么T1也是不能運行的,假設T2運行到了某個地方,T2主動放棄CPU,T1開始運行,運行到了某個地方,它也主動放棄CPU,那這個時候,T3要運行,假設運行到了某個地方,T2說它要運行,同樣,由于是不可剝奪性內核,那么T2也運行不了,T3接著運行,假設運行到了某個地方,T1說它要運行,同樣,由于是不可剝奪性內核,那么T1也運行不了,只有T3主動放棄CPU,這個時候,T1才會執行,T1執行完畢后,T2才開始執行。
從這我們可以看出一個問題,不可剝奪性內核的好處就是只要這個任務不主動放棄CPU,那么別的任務是不能被搶奪的,這是他的一個好處,這就是說,這個任務它的響應速度是比較快的,但是,這個不可剝奪性內核有一個最大的缺點,比如,T2這個優先級高的他要執行,但是T3不主動放棄CPU,T2還是沒辦法執行,直到T3主動放棄CPU了,T3執行完畢了,它才能執行。這個時候,我們可以看到,雖然這個T2這個優先級比較高,但是你的允許還是放在了T3的后面,這個時候就出現了一個問題,我優先級比較高,但是我還是不能立馬被執行,那這個時候就有點不符合我們優先級調度的算法,這個是我們的可剝奪性內核,這個我們需要注意。
可剝奪性內核
就是在運行的過程中,這個內核,可以被剝奪。
同樣給大家舉個例子,假設系統中還是有5個任務,T1,T2,T3,T4,T5,這個時候,這5個任務開始分配優先級,0,1,2,3,4,假設T4這個任務在執行,它在執行的過程中,它說我要執行,由于T3這個優先級比較高,它就會過來立馬執行,T3這個任務在執行,它在執行的過程中,假設這個T2它說我要執行,那么它會打斷T3來執行T2,當T2執行完畢,讓出CPU以后,T3接著往下執行,這個就是可剝奪性內核,從這我們可以看出可剝奪性內核對于一個優先級較低的來說,它的實時性可能不是很好,但是對于一個優先級較高的來說,它的實時性是相當好的,只要這個任務需要執行,他就會立馬執行,這個就是可剝奪性內核。
可重入函數:
實現了一個字符拷貝這樣的一個函數
//可重入函數
void strcpy(char *dest,char *src,int len)
{
while(len--)
{
*dest++ = *src++;
}
}
//不可重入函數
int Temp;
void swap(int *x,int *y)
{
Temp = *x;
*x = *y;
*y = Temp;
}
這個函數實現了兩個數據的交換,假設在任務A中,調用了swap這個函數,它需要對a和b這兩個數進行交換,假設a=100,b=20,但是,當這個任務執行到一半的時候,就是執行到 *x = *y;這一步的時候,Temp=100,a=20,已經交換過來了,假設在這個地方,任務A被任務B搶占了,被任務B搶占以后,任務B也來搶占swap這個函數,調用這個函數以后,但是它傳入的參數不再是a和b了,而是c和d,c=50,d=40,這個時候,它再來執行這個, Temp=*50,c=40,這個時候,*y = Temp也就是=40,d=50,它完成了這個交換過程,交換完畢以后,假設再回到任務A來執行,那就是從這個地方執行,*x = *y,*y = Temp,由于Temp是一個全局變量,在上一個任務當中Temp已經變成了50,也就是說, *y = 50,也就是b=50,那這個時候,我們就發現出問題了,我們想要交換的是a=100,b=20,但是交換的結果卻是a=20,b=50,那么我們就發現swap這個函數,在執行的時候發生了錯誤,這個函數就被稱為不可重入函數,為什么不可重入函數呢?
從這里我們可以看出,它使用了Temp全局變量,所以造成了一個不可重入。從這里可以看出,要想讓一個函數變成可重入函數,我們只需要做到一點,不使用全局變量,只使用局部變量就行了,這個時候就出現了一個問題,為什么只使用局部變量就可以變成可重入函數呢?
因為局部變量它是保存在堆棧中,而每個任務它會有自己的堆棧,A和B的堆棧是互不沖突的,所以使用局部變量就可以變成可重入函數,那全局變量不是保存在堆棧中,我們誰都可以訪問這個區域,比如B可以訪問這個區域,A也可以訪問這個區域,那這樣的話,如果任何一方想訪問這個區域,都會造成這個區域的數據被修改,所以這個函數就會成為不可重入函數。
?
原文鏈接:http://www.maiziedu.com/wiki/iot/ucoskernel/
轉載于:https://www.cnblogs.com/maizi008/p/5939231.html
總結
以上是生活随笔為你收集整理的ucos操作系统的内核有哪些调度方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 作业三总结
- 下一篇: gcc/g++ 以及makefile