版權聲明:本文爲本文爲博主原創文章,轉載請註明出處。若有錯誤,歡迎指正。博客地址:https://www.cnblogs.com/wsg1100/
操作系統
同步:任務間的直接制約關係,A要繼續執行須要B完成某一個操做操做才能繼續進行。
互斥:任務間的間接制約關係,A訪問了資源B就不能去訪問,必須等A訪問完了才行。線程
操做系統提供了任務間的同步互斥機制,如信號量信號量(sem)、互斥鎖(mutex)、條件變量(cond)等,抽象來講這些同步互斥鎖本都是操做系統管理的一種資源,與消息隊列(mq)、xddp/bufp/iddp、信號(signal)、一個驅動設備等同樣。3d
對於每種資源,資源管理要有兩個基本機制:訪問控制和資源的保存。code
name
(bind操做時)快速定位到任務訪問的資源,並將其與操做的任務聯繫起來。xenomai內核中,任務間共享資源(一切涉及同步互斥的資源)抽象爲對象xnsynch,這裏的資源不只限於信號量(sem)、互斥鎖(mutex)、xnpipe、消息隊列(mq)、事件(event)、條件(cond)、一個驅動設備、以及xnregister…..,xnsynch與xenomai調度緊密結合,來實現上面所說的訪問控制,本文所說的優先級倒置問題在該模塊中實現。對象
xenomai內核中將任務間的一切資源(包括xenomai內核態一些資源)使用內核對像xnobject
表示,內核中的全部內核對象使用xnregistry
來保存,因爲xenomai內核工做過程當中不能動態去申請內存,因此xnregistry
大小通常是內核配置時配置的,具體內存分配在xenomai初始化時調用xnregistry_init()初始化xnregistry時分配。blog
內核對象管理xnregistry分析,請關注本博客後續文章內核對象管理—xnregistry繼承
xenomai內存管理,請關注本博客後續文章xenomai實時系統內存池管理--xnheap隊列
xenomai調度管理,請關注本博客後續文章xenomai任務管理系列事件
xnregistry
:保存內核對象,提供內核對象存儲和快速檢索。ip
xnsynch
:資源抽象,提供線程與資源的同步互斥管理機制。
具體的線程間內核資源(對象):信號量(sem)、消息隊列(mq)、xddp/bufp/iddp、事件(event)、條件變量(cond)、一個驅動設備、xnregister(xnregister的訪問也互斥)…..。
下面介紹優先級倒置也稱優先級反轉,會在下一篇文章分析xnsynch
,如何解決優先級倒置問題。
在基於優先級調度下,會出現下面狀況(例子中的信號量爲二值信號量與互斥量等效).
圖中,三個任務t一、t二、t3的優先級分別是高、中、低。低優先級任務t3經過獲取信號量來獲取一些資源。t3運行一段時間後,t1就緒搶佔t3獲得運行,一段時間後t1須要相同信號量保護的資源時,t1因爲獲取不到信號量而阻塞。被t1搶佔的t3獲得繼續運行。接着低優先級任務t3受到中優先級任務t2的搶佔,t2的搶佔致使t3遲遲沒法釋放信號量,這種狀況可能會持續存在,最終致使高優先級任務t1無限期阻塞。在這種狀況下,優先級發生了翻轉,任務t2老是先於任務t1運行。(xenomai中優先級數值越大,優先級越高)
這就是優先級反轉轉問題(Priority Inversion and Priority Inheritance),即當一個高優先級任務經過信號量機制訪問共享資源時,該信號量已被一低優先級任務佔有,而這個低優先級任務在訪問共享資源時可能又被其它一些中等優先級任務搶先,所以形成高優先級任務被許多具備較低優先級任務阻塞,實時性難以獲得保證。
經過上圖可知,只要t3不被中優先級任務搶佔,儘快釋放信號量就好了,因此在t1阻塞期間須要給t3一個足夠高的優先級。避免優先級反轉有優先級天花板和優先級繼承兩種辦法。
優先級天花板是當任務申請某資源時, 把該任務的優先級提高到可訪問這個資源的全部任務中的最高優先級, 這個優先級稱爲該資源的優先級天花板。
優先級繼承是當任務t1 申請共享資源S 時, 若是S正在被任務t3 使用,經過比較任務t3 與t1的優先級,如發現任務t3 的優先級小於t1的優先級, 則將任務t3的優先級提高到t1的優先級,等t3 釋放資源S 後,再恢復任務t3 的原優先級。xenomai內核使用該方式,優先級反轉後的示意圖以下。
如上圖所示,經過優先級繼承,在t1被阻止的時間內將t3的優先級提高到t1的優先級來解決優先級反轉,這樣能夠保護t3和間接t1免受t2的搶佔。
以上爲單個互斥信號的狀況,在真實環境中,每每是多個信號量、多個任務,下圖爲多個任務與多個互斥信號量交互的示例:
① 低優先級爲10的任務t3獲取信號量s1;
② 任務t3獲取信號量s2;
③ 任務t2搶佔運行後嘗試獲取信號量s1時阻塞;
④ 任務t3繼承t2的優先級30繼續執行;
⑤ 優先級爲90的t1搶佔t3;
⑥ 任務t1嘗試獲取信號量s2阻塞;
⑦ 任務t3繼承t1的優先級90繼續執行;
⑧ 任務t3釋放信號量s1,優先級繼續保持爲90;
⑨ 任務t3釋放信號量s2,並恢復優先級10;
⑩ 任務t1獲取信號量s2搶佔運行。