本文引自鏈接http://www.52rd.com/Blog/Detail_RD.Blog_imjacob_16830.html?WebShieldDRSessionVerify=COR6tnpfsOXExxEAO6Z6 本文引自鏈接http://www.52rd.com/Blog/Detail_R ...
本文引自鏈接http://www.52rd.com/Blog/Detail_RD.Blog_imjacob_16830.html?WebShieldDRSessionVerify=COR6tnpfsOXExxEAO6Z6
今天再看《嵌入式軟體系統教程》((美)西蒙 著,陳向群 等譯) ,裡面講到關中斷會關了任務調度,作者沒說原因,我也不知道為什麼,所以查了查網路。
===============================================================
在這個網址http://www.hqwic.com/bbs/topic.aspx?topicid=11253上有一個討論,我覺得很有道理。很明顯觀點是關了中斷,只是禁止了搶占,但並沒有禁止調度。
這樣看來,那本書上的觀點是不正確的??
把一些自認為很有道理的解釋摘抄下來:
首先說明一下,引起調度(任務切換)的原因有兩個: 1、任務主動進入了阻塞狀態,就像2樓說的,調用了所謂的切換函數。 2、中斷,中斷服務程式(isr)改變了任務狀態,使某個比當前任務優先順序高的任務進入了準備好(ready)狀態,於是內核調用了切換函數。 這兩個原因可以稱為“同步方式調度”和“非同步方式調度”。搶占的意義在於:如果高優先順序任務進入準備好狀態後,操作系統可以立即調度(任務切換),將高優先順序任務投入運行。而這些動作對低優先順序任務來說是完全透明的。 但是,誰?!使高優先順序任務進入準備好狀態,而又對低優先順序任務透明呢?就是“中斷”。 所以說,“搶占”是系統進行了“非同步方式調度”的結果。既然關閉了中斷,也就禁止了搶占。樓主,你想明白了嗎? 在這裡也要糾正一下3樓和5樓:“關了中斷,就禁止了調度”這種說法不妥。關了中斷,只是禁止了搶占,但並沒有禁止調度啊。 |
正在運行的任務是所有就緒任務中優先順序最高的,如果要運行其它優先順序更高的任務,就只有發生了某些事件使得更高優先順序的任務進入了就緒狀態,而這些事件只有在兩種情況下發生: 1. 中斷改變了任務狀態 2. 運行中的任務主動使優先順序更高的任務進入就緒狀態 2 相當於是主動放棄CPU占有權,所以說搶占是由中斷引起的,是非同步調度的結果(??這裡邏輯有點問題。作者的意思可能是 :2是非搶占的,主動的,1是搶占的,被動的,所以說搶占是由中斷引起的,是非同步調度的結果。by imjacob) 所以就是你說的結論,關中斷只是關了搶占,而運行中的任務依然可以主動做任務調度。這裡uC/OS有一個非常重要的前提條件,就是 運行中的任務是所有就緒任務中優先順序最高的,如果沒有事件發生就會一直運行直到完成。 |
所以,你最開始的疑問:“關中斷只是屏蔽了中斷,並沒有阻止任務切換,高優先順序的任務任然可以搶占CPU並訪問臨界區和共用變數啊” 關 中 斷 之 後, 任 何 外 部 事 件 都 不 能 打 擾 處 理 機 連 續 執 行 臨 界 區 程 序。 如 果 臨 界 區 程 序 本 身 並 不 包 含 使 它 的 進 程 轉 變 為 封 鎖 狀 態 的 因 素, 那 麽 這 種 方 法 就 能 保 證 臨 界 區 作 為 一 個 整 體 執 行。 這 種 方 法 的 優 點 是 簡 單、 可 靠, 但 是 它 也 有 一 定 的 局 限 性 和 若 乾 不 足 之 處。 (1) 它 不 能 用 於 多 處 理 機 系 統。 其 原 因 是: 由 於 該 系 統 中 的 多 個 處 理 機 都 有 其 各 自 的 中 斷 開 關, 因 此 一 個 處 理 機 並 不 能 阻 止 在 其 它 處 理 機 上 運 行 的 進 程 進 入 同 類 臨 界 區。 (2) 在 臨 界 區 中 如 果 包 含 有 使 執 行 它 的 進 程 有 可 能 進 入 封 鎖 狀 態 的 因 素, 則 也 不 能 使 用 這 種 方 法。 因 為 在 該 進 程 進 入 封 鎖 狀 態 後, 系 統 將 調 度 另 一 進 程 使 用 處 理 機, 如 果 需 要, 該 進 程 也 可 以 執 行 臨 界 區 程 序, 不 會 受 到 任 何 阻 攔, 所 以 在 這 種 情 況 下, 開、 關 中 斷 不 能 實 施 臨 界 區 互 斥。 (3) 如 果 臨 界 區 比 較 長, 則 本 法 會 降 低 中 斷 響 應 速 度。 (4) 這 是 一 把 鎖 處 理 各 類 臨 界 區, 不 必 要 地 擴 大 了 互 斥 範 圍。 |
“為什麼關中斷開中斷可以作為互斥條件,而且是最粗暴的方式呢?” 按上面的解釋,開關中斷是可以作為互斥條件的,但的確很粗暴。眾所周知,嵌入式實時操作系統最關鍵的性能指標之一便是中斷響應時間。中斷響應時間越短,實時性就越好。但很多嵌入式操作系統(包括uCos在內)的中斷響應時間都比較長。原因就是在這些操作系統中大量使用了關中斷這種“粗暴”的方式(OS_ENTER_CRITICAL),你可以看看uCos, FreeRTOS等操作系統的源碼,這樣的寫法比比皆是。當然,不用OS_ENTER_CRITICAL是不可能的,那會造成數據混亂,這是它們的系統結構所決定的。 如果能保證在中斷處理中不去寫共用數據(包括可能改變共用數據的系統調用),就可以不用關中斷了,但這需要改變系統結構,把中斷服務分為兩個部分,這就是所謂的“Top half 和 Bottom half”。如果想瞭解具體,你可以去網上查查。應用這種技術的操作系統有Linux, Windows, eCos等。 |
不用中斷來進行調度的操作系統,就是沒有搶占,說白了就是一個協作式操作系統,怎麼會一定導致死鎖?難道搶占式操作系統就不會出現死鎖? 其實,死鎖是多個任務在企圖獲取多個獨占(exclusive)資源時,可能導致的一種所有參與任務全部被阻塞的狀態。這分明是屬於應用程式的邏輯概念,而調度則是屬於操作系統的邏輯概念,怎麼能混為一談。 |
後記:
另外在查網路的時候,還看到一本中國人的書<操作系統教程>(http://books.google.cn/books?id=X8lmMtog0XcC&pg=PT59&lpg=PT59&dq=%E5%85%B3%E4%B8%AD%E6%96%AD+%E4%BA%92%E6%96%A5&source=bl&ots=GwX4qh0hM0&sig=j1ieBs1RvU-bTpkddC4OyxoneTc&hl=zh-CN&sa=X&oi=book_result&resnum=2&ct=result) 3.2.2 硬體方法中寫:“ 因為cpu只在發生中斷時引起進程切換,這樣禁止中斷就能保證當前運行進程將臨界區代碼順利執行完,從而保證了互斥的正確實現。”顯然也是錯的。我們可以當作練習把它改正了。哈哈。
評 論 4樓 52RD網友 發表於 2008-11-27 12:29 回覆 這是一個不淺也不深的問題,如果RTOS支持時間按片,那麼與OS TIMER INT無法產生,基於時間片的調度就無法進行。 中斷關了,CPU在公所,只有OS,你想想與這個有關嗎? 3樓 JohnsonJin 發表於 2008-11-26 13:15 回覆 所以,關中斷不會禁止調度,還要在關中斷處理的這個過程中不調用任何的OS函數,至少不能調用哪些會引起調度的函數。比如:資源申請,(記憶體申請,萬一記憶體沒有了呢),semaphore等同步函數的操作,給其他進程發消息....。 2樓 JohnsonJin 發表於 2008-11-26 13:11 回覆 以上大部分都片面!我們先看調度發生的時機: 1. 中斷 2. 系統調用。 然後我們看中斷為什麼會引起調度,通常中斷會做一些處理,然後引起上層的“註意”。上層包括進程和負責進程調度的OS。如果系統支持時間片調度,那時鐘中斷引起OS把時間片到期的任務試著切換出去(如果沒有相同優先順序的進程在等待CPU的話,就不切換)。如果中斷處理所需要引起的上層註意者是進程(中斷ISR給進程發消息,信號,釋放semaphore等),也就是本來在等待事件的進程被放到了ready隊列。在中斷處理結束的時候,OS的中斷後處理過程會重新調度。這個時候就看誰的優先順序高了,如果喚醒的是高優先順序的進程,則做進程切換。系統調用其實也是一樣的道理,在系統調用中,通常會引起資源或者鎖的釋放,或者觸發其他高優先順序進程ready,在系統調用結束的一刻,OS會重新嘗試調度。