linux核心搶占的幾個細節

2021-05-21 19:34:55 字數 1605 閱讀 7089

郵件列表每天都能讓我學到新東西,感謝他!有朋友問preempt_active有什麼用,我給出了最簡單的回答,就是避免被搶占的程序被無情的趕出執行佇列。這個回答顯然不能讓那位朋友滿意...

程序一旦呼叫了schedule,如果再次被排程執行,那麼有下面幾種可能:1.狀態為task_running,處於執行佇列,那麼它肯定有機會再執行;2.處於睡眠佇列,那麼一旦條件滿足被喚醒,那麼它就會執行。那麼如果乙個程序被搶占的話,而且它不在執行佇列,那麼怎麼再讓它執行呢?答案是它不能執行了。為了避免這種情況,就必須避免處於非task_running的程序被搶占的程序不被趕出執行佇列,也就是下面的**,schedule的**:

if (prev->state && !(preempt_count() & preempt_active)) while (unlikely(test_thread_flag(tif_need_resched)));

除了這裡之外,在早一些的核心中從中斷返回核心空間時如果要搶占,在entery.s中也會加上這個這個preempt_active。現在還有乙個問題,就是為何wait_event要用那種實現方式呢?為何需要乙個迴圈呢?我的回答就是:這種情況下程序之所以能被喚醒就是因為它加入了乙個睡眠佇列,如果如你所說在schedule之後直接判斷condition的話是不安全的,因為喚醒不一定是因為條件滿足了,萬一兩個程序同時被喚醒那很可能有乙個程序條件不能滿足,如果正好此時程序被搶占,那麼這個程序就沒有機會加入睡眠佇列了,也就沒有機會被喚醒了,雖然preempt_active保證了這個程序不出執行佇列,但是卻失去了程式的本意,程式的本意是通過喚醒執行佇列來使程序執行,而此時卻成了完全依據優先順序了,即使條件滿足因為這個程序不在睡眠佇列也不會被喚醒,系統就亂掉了。

其實很簡單,必須在將程序加入到睡眠佇列以後再判斷條件,因為這樣可以不漏掉喚醒通知,如果反過來的話,就是先判斷再加入睡眠佇列,如果在加入之前其它程序喚醒了這個睡眠佇列,那麼這個程序就會漏掉這次喚醒,之所以會有乙個迴圈是因為可能不止乙個程序被喚醒,那麼就會出現競爭,這個迴圈就是為了競爭而設定的,這個迴圈保證了每個出了這個迴圈的程序都能安全帶著結果為真的條件。

另外,說到task_running這個狀態,又有人問了,為何在缺頁中要把程序狀態設定為task_running,難道缺頁前不是task_running嗎?大部分情況下應該是,可是linux核心不敢保證,之所以在handle_mm_fault中將程序狀態設定為task_running是為了保證在缺頁處理中如果睡眠,那麼程序可以被喚醒,舉個例子,在select中,當程序被設定為非task_running之後還會copy_from_user,而這卻可能引起缺頁。如果不把程序狀態設定為task_running,那麼萬一在page fault中schedule了,那麼這個程序就會被趕出執行佇列,就再也回不來了,為了預防之,措施是:在任何呼叫schedule的地方分辨狀態,然後設定程序狀態,比如前面說的用preempt_active來預防,另外就是像handle_mm_fault中做到的一樣,盡量使程序在task_runnabe狀態下進入schedule。不過我想是不是現在這個應該去掉了,即使在缺頁中不把程序設定為執行態,如果非要排程,也在之前設為執行臺了。

active_preempt的作用:防止已經處於非執行態的程序還沒有加入睡眠佇列的時候就被搶占然後剔除出執行佇列。這樣就永遠也回不來了,雖然這種情況很少見,一般都是先將程序放到睡眠佇列再設定狀態。

Linux 核心搶占

核心搶占 kernel preemption 是一種有效的降低系統響應延時的方法。在核心裡,有三個相關的配置選項。顧名思義,不開啟核心搶占。這是很多伺服器的預設配置選項。在沒有開啟核心搶占的時候,程序的排程時機僅僅發生在非常有限的幾處 程序自己主動觸發排程,例如 通過sleep schedule y...

Linux核心 了解Linux核心搶占

目錄 無強制搶占 可搶占核心 自願核心搶占 完全實時搶占 在配置linux核心時,我們可以設定一些影響系統行為的引數。您可以使用不同的優先順序,排程類和搶占模型。了解並選擇正確的引數非常重要。在這篇文章中,我將介紹不同的搶占模型,以及每種模型如何影響使用者和核心行為 如果配置核心 使用make me...

Linux核心搶占 2

早期的linux核心是不可搶占的。它的排程方法是 乙個程序可以通過schedule 函式自願地啟動一次排程。非自願的強制性排程只能發生在每次從系統呼叫返回的前夕以及每次從中斷或異常處理返回到使用者空間的前夕。但是,如果在系統空間發生中斷或異常是不會引起排程的。這種方式使核心實現得以簡化。但常存在下面...