天天看點

作業系統--排程學習筆記(4)--多處理器和實時排程

多處理器系統可以分為以下幾類:

  1. 松耦合、分布式多處理器、叢集;
  2. 專門功能的處理器,例如I/O處理器;
  3. 緊耦合多處理:有一系列共享同一個記憶體并在作業系統完全控制下的處理器組成,我們這裡要讨論的就是這種處理器;

linux采用動态負載均衡的政策,不論是否給程序配置設定專用的處理器,都需要主從式或對等式的方法吧程序配置設定給處理器。主從式就是把核心功能放在特定的處理器上運作,主處理器負責排程業務,但這種方法可能因為主處理器的失敗導緻整個系統失敗,同時主處理器容易成為瓶頸;在對等式結構中,作業系統可以在任何一個處理器中執行,但必須采用默寫技術來解決和同步資源競争請求。

對于程序的排程,多處理器使用FCFS原則,或者在靜态優先級方案中使用FCFS。這也很好地解釋了為啥while true死循環會耗幹一顆CPU。

線程排程采用負載配置設定的方式,這是使用最多的一種方案。

Linux的排程方式有三類:SCHED_FIFO,SCHED_RR和SCHED_OTHER,其中SCHED_OTHER在linux2.6以後被改為了一種全新的O(1)排程政策,SCHED_RR其實就是帶時間片的SCHED_FIFO。一般而言高優先級的任務能夠被配置設定的優先級更大。

其實~~貌似各種不同的排程算法之間的差别對性能來說,貌似也不是很重要的說~~

作業系統--排程學習筆記(4)--多處理器和實時排程

但我們還是要詳細講講程序的排程。

接下來,更深入的說

排程程式決定什麼時候停止一個程序的運作,以便其他程序能夠得到執行機會。程序被槍戰之前能夠運作的時間(即時間片)是預先設定好的。當然對于非搶占式系統,例如遠古的Mac OS9和windows3.1,程序會一直執行,除非它自動停止,目前主流的作業系統均為搶占式的。

linux2.6有一個全新的排程算法——反轉樓梯最後期限排程算法(Rotating Staircase Deadline Scheduler)RSDL,并在2.6.23後采用完全公平排程算法(CFS)。現有Linux系統中,可以通過nice值區分程序時間片的長短,nice值越小,優先級越高。CFS的最小時間片粒度是1ms,但通過vruntime的方法,粒度已經被調整為1ns。CFS的排程核心是,選擇最小的vruntime任務,接下來,我們看看源碼。

CFS使用紅黑樹來組織可運作程序隊列。

挑選下一個任務時,選擇樹最左側的葉子節點,對應API函數為__pick_next_entity,并且最左側的葉子節點往往會被緩存起來;

程序休眠時,從可執行的紅黑樹移除,放入等待隊列,然後調用shedule()選擇執行其他程序,喚醒過程正好相反;

向樹中加入程序時,fork()函數會調用enqueue_entity函數,從樹中删除對應的函數為dequeue_entity。

程序排程的主要入口點是函數schedule() ,他會調用pick_next_task(),pick_next_task會以優先級為序,從高到低,依次檢查每一個排程類,并從優先級最高的排程類中,選擇最高優先級的程序。

加入到等待隊列的步驟如下:

作業系統--排程學習筆記(4)--多處理器和實時排程

上下文切換:從一個可執行程序切換到另一個可執行程序,代碼定義在kernel/sched.c中的context_switch()函數,它完成兩項基本工作:

1、調用switch_mm函數,把虛拟記憶體從上一個程序映射切換到新程序中;

2、調用siwtch_to從上一個程序的處理器裝狀态切換到新程序的處理器狀态;

程序中有一個need_resched字段來表明是否需要重新執行一次排程,2.6版本中它在thread_info結構體裡。

當核心即将傳回使用者控件的時候,會檢查need_resched,如果need_resched被設定,會導緻schedule函數被調用,此時發生使用者搶占。總的來說,發生使用者搶占的情況有兩種,一個是從系統調用傳回使用者空間時,另一個是從中斷程式傳回使用者空間時;

另一個搶占式核心搶占,與大部分Unix系統不同,Linux完整地支援核心搶占。核心搶占會發生在:1、中斷處理程式正在執行,且傳回核心控件前;2、核心代碼再一次具有可搶占性的時候;3、核心中的任務顯示調用Schedule;4、核心任務阻塞;這裡需要說明,搶占的前提是相應的程序時沒有鎖的;

繼續閱讀