我被要求描述兩個不同進程之間的上下文切換(1)以及(2)同一進程中兩個不同線程之間所涉及的步驟。上下文切換的步驟
- 在上下文切換期間,內核會將舊進程的上下文保存在PCB中,然後加載預定運行的新進程的保存上下文。
- 操作系統可以調度同一進程中兩個不同線程之間的上下文切換,以便它們似乎並行執行,因此通常比兩個不同進程之間的上下文切換快。
這是太籠統了,還是你會添加什麼來解釋清楚的過程?
我被要求描述兩個不同進程之間的上下文切換(1)以及(2)同一進程中兩個不同線程之間所涉及的步驟。上下文切換的步驟
這是太籠統了,還是你會添加什麼來解釋清楚的過程?
由於過程切換總是涉及線程切換,因此以相反的順序解釋它們要容易得多。
單核CPU上的一個典型線程上下文切換髮生這樣的:
所有上下文切換由一個「中斷」啓動。這可能是運行驅動程序的實際硬件中斷(例如,來自網卡,鍵盤,內存管理或計時器硬件)或軟件調用(系統調用),它執行類似硬件中斷的調用序列進入操作系統。在驅動程序中斷的情況下,操作系統提供了一個驅動程序可以調用的入口點,而不是執行「正常」直接中斷返回&,因此如果驅動程序需要OS設置線程,則允許驅動程序通過OS調度程序退出準備好了,(例如它已經發出信號量的信號)。
非平凡系統必須啓動硬件保護級別更改才能進入內核狀態,以便可以訪問內核代碼/數據等。
被中斷的線程的核心狀態必須被保存。在一個簡單的嵌入式系統中,這可能只是將所有寄存器推送到線程堆棧並將堆棧指針保存在其線程控制塊(TCB)中。
許多系統在此階段切換到OS專用堆棧,以便大量的OS內部堆棧要求不會在每個線程的堆棧中產生。
可能需要標記出現中斷狀態更改的線程堆棧位置,以允許嵌套中斷。
驅動程序/系統調用運行,並可以通過從不同線程優先級的內部隊列中添加/刪除TCB來更改就緒線程集。網卡驅動程序可能已經設置了一個事件,或者發出了另一個線程正在等待的信號量,以便線程將被添加到就緒集中,或者正在運行的線程可能已經調用了sleep(),因此被選擇將其自身從ready套件中移除。
運行OS調度程序算法以決定下一個要運行的線程,通常是優先級最高的就緒隊列的前端隊列。如果下一個運行的線程屬於與先前運行的線程不同的進程,那麼這裏需要一些額外的東西(見後面的內容)。
從TCB爲該線程保存的堆棧指針被檢索並加載到硬件堆棧指針中。
恢復所選線程的核心狀態。在我的簡單系統上,寄存器將從所選線程的堆棧中彈出。更復雜的系統必須處理恢復用戶級保護。
執行中斷返回,將執行轉移到選定的線程。
在多核CPU的情況下,事情更復雜。調度程序可能會決定當前在另一個核心上運行的線程可能需要停止並由剛準備好的線程替換。它可以通過使用其處理器間驅動程序來硬件中斷運行必須停止的線程的內核。在這種操作的複雜性,對所有其他的東西上面,是一個很好的理由,以避免編寫操作系統內核:)
一個典型的進程上下文切換髮生這樣的事情:
進程上下文切換啓動通過線程上下文切換,所有上述1-9都將需要發生。
在上面的步驟5中,調度程序決定運行屬於與擁有先前運行的線程的進程不同的進程的線程。
內存管理硬件必須加載新進程的地址空間,即任何允許新進程的線程訪問其內存的選擇器/段/標記/任何內容。
任何FPU硬件的上下文需要從PCB保存/恢復。
可能還有其他需要保存/恢復的進程專用硬件。
在任何實際系統中,機構是體系結構相關和上面是一個粗略的和不完全的導要麼上下文切換的影響。還有一些流程開關生成的其他開銷並不完全是開關的一部分 - 在進程切換後可能會有額外的緩存刷新和頁面錯誤,因爲它的某些內存可能已被分頁出來,到擁有之前運行的線程的進程。
我希望我能提供更詳細/清晰的圖片。
首先,OS調度線程,而不是進程,因爲線程是系統中唯一的可執行單元。進程切換隻是一個線程切換,其中線程屬於不同的進程。由於這種情況在一般的開關程序中很常見。
調度程序應該被調用。有三種基本情況:
在所有情況下,爲了能夠執行線程切換,應該將控制權交給內核。在無意識開關的情況下,這種控制過程通過中斷執行,在自願(和半自願)情況下,通過系統調用傳遞控制。
在這兩種情況下,進入內核都是由CPU輔助的。處理器執行權限檢查,記住線程被搶佔的位置(以便能夠在將來恢復),從線程堆棧的用戶部分切換到其內核對象,並將控制權傳遞給預定義的知名點內核代碼。
總結的一些注意事項:
(來源:Context switch)
能解釋單芯上下文切換的步驟4中更詳細?爲什麼嵌套中斷需要「標記」?另外,寄存器的確切位置在哪裏? (假設Linux) –