歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> 關於Linux >> 進程上下文VS中斷上下文

進程上下文VS中斷上下文

日期:2017/3/1 17:14:18   编辑:關於Linux
進程上下文VS中斷上下文 內核空間和用戶空間是現代操作系統的兩種工作模式,內核模塊運行在內核空間,而用戶態應用程序運行在用戶空間。它們代表不同的級別,而對系統資源具有不同的訪問權限。內核模塊運行在最高級別(內核態),這個級下所有的操作都受系統信任,而應用程序運行在較低級別(用戶態)。在這個級別,處理器控制著對硬件的直接訪問以及對內存的非授權訪問。內核態和用戶態有自己的內存映射,即自己的地址空間。 www.2cto.com 處理器總處於以下狀態中的一種: 1、內核態,運行於進程上下文,內核代表進程運行於內核空間; 2、內核態,運行於中斷上下文,內核代表硬件運行於內核空間; 3、用戶態,運行於用戶空間。 用戶空間的應用程序,通過系統調用,進入內核空間。由內核代表該進程運行於內核空間,這就涉及到上下文的切換,用戶空間和內核空間具有不同的地址映射,通用或專用的寄存器組,而用戶空間的進程要傳遞很多變量、參數給內核,內核也要保存用戶進程的一些寄存器、變量等,以便系統調用結束後回到用戶空間繼續執行。 所謂的“進程上下文”,就是一個進程在執行的時候,CPU的所有寄存器中的值、進程的狀態以及堆棧上的內容,當內核需要切換到另一個進程時,它需要保存當前進程的所有狀態,即保存當前進程的進程上下文,以便再次執行該進程時,能夠恢復切換時的狀態,繼續執行。 硬件通過觸發信號,導致內核調用中斷處理程序,進入內核空間。這個過程中,硬件的一些變量和參數也要傳遞給內核,內核通過這些參數進行中斷處理。 www.2cto.com 所謂的“中斷上下文”,其實也可以看作就是硬件傳遞過來的這些參數和內核需要保存的一些其他環境(主要是當前被中斷的進程環境)。 當一個進程在執行時,CPU的所有寄存器中的值、進程的狀態以及堆棧中的內容被稱為該進程的上下文。當內核需要切換到另一個進程時,它需要保存當前進程的所有狀態,即保存當前進程的上下文,以便在再次執行該進程時,能夠必得到切換時的狀態執行下去。在LINUX中,當前進程上下文均保存在進程的任務數據結構中。在發生中斷時,內核就在被中斷進程的上下文中,在內核態下執行中斷服務例程。但同時會保留所有需要用到的資源,以便中繼服務結束時能恢復被中斷進程的執行。 Linux內核工作在進程上下文或者中斷上下文。提供系統調用服務的內核代碼代表發起系統調用的應用程序運行在進程上下文;另一方面,中斷處理程序,異步運行在中斷上下文。中斷上下文和特定進程無關。 上下文context:上下文簡單說來就是一個環境,相對於進程而言,就是進程執行時的環境。具體來說就是各個變量和數據,包括所有的寄存器變量、進程打開的文件、內存信息等。 一個進程的上下文可以分為三個部分:用戶級上下文、寄存器上下文以及系統級上下文。 用戶級上下文: 正文、數據、用戶堆棧以及共享存儲區; 寄存器上下文: 通用寄存器、程序寄存器(IP)、處理器狀態寄存器(EFLAGS)、棧指針(ESP); 系統級上下文: 進程控制塊task_struct、內存管理信息(mm_struct、vm_area_struct、pgd、pte)、內核棧。 當發生進程調度時,進行進程切換就是上下文切換(context switch).操作系統必須對上面提到的全部信息進行切換,新調度的進程才能運行。而系統調用進行的是模式切換(mode switch)。模式切換與進程切換比較起來,容易很多,而且節省時間,因為模式切換最主要的任務只是切換進程寄存器上下文的切換。 進程上下文主要是異常處理程序和內核線程。內核之所以進入進程上下文是因為進程自身的一些工作需要在內核中做。例如,系統調用是為當前進程服務的,異常通常是處理進程導致的錯誤狀態等。所以在進程上下文中引用current是有意義的。 內核進入中斷上下文是因為中斷信號而導致的中斷處理或軟中斷。而中斷信號的發生是隨機的,中斷處理程序及軟中斷並不能事先預測發生中斷時當前運行的是哪個進程,所以在中斷上下文中引用current是可以的,但沒有意義。事實上,對於A進程希望等待的中斷信號,可能在B進程執行期間發生。例如,A進程啟動寫磁盤操作,A進程睡眠後B進程在運行,當磁盤寫完後磁盤中斷信號打斷的是B進程,在中斷處理時會喚醒A進程。 內核可以處於兩種上下文:進程上下文和中斷上下文。在系統調用之後,用戶應用程序進入內核空間,此後內核空間針對用戶空間相應進程的代表就運行於進程上下文。異步發生的中斷會引發中斷處理程序被調用,中斷處理程序就運行於中斷上下文。中斷上下文和進程上下文不可能同時發生。   運行於進程上下文的內核代碼是可搶占的,但中斷上下文則會一直運行至結束,不會被搶占。因此,內核會限制中斷上下文的工作,不允許其執行如下操作:   (1) 進入睡眠狀態或主動放棄CPU; 由於中斷上下文不屬於任何進程,它與current沒有任何關系(盡管此時current指向被中斷的進程),所以中斷上下文一旦睡眠或者放棄CPU,將無法被喚醒。所以也叫原子上下文(atomic context)。   (2) 占用互斥體; 為了保護中斷句柄臨界區資源,不能使用mutexes。如果獲得不到信號量,代碼就會睡眠,會產生和上面相同的情況,如果必須使用鎖,則使用spinlock。   (3) 執行耗時的任務; 中斷處理應該盡可能快,因為內核要響應大量服務和請求,中斷上下文占用CPU時間太長會嚴重影響系統功能。在中斷處理例程中執行耗時任務時,應該交由中斷處理例程底半部來處理。   (4) 訪問用戶空間虛擬內存。 因為中斷上下文是和特定進程無關的,它是內核代表硬件運行在內核空間,所以在中斷上下文無法訪問用戶空間的虛擬地址   (5) 中斷處理例程不應該設置成reentrant(可被並行或遞歸調用的例程)。 因為中斷發生時,preempt和irq都被disable,直到中斷返回。所以中斷上下文和進程上下文不一樣,中斷處理例程的不同實例,是不允許在SMP上並發運行的。   (6)中斷處理例程可以被更高級別的IRQ中斷。 如果想禁止這種中斷,可以將中斷處理例程定義成快速處理例程,相當於告訴CPU,該例程運行時,禁止本地CPU上所有中斷請求。這直接導致的結果是,由於其他中斷被延遲響應,系統性能下降。
Copyright © Linux教程網 All Rights Reserved