Linux系统的中断、系统调用和调度概述【转】
轉(zhuǎn)自:http://blog.csdn.net/yanlinwang/article/details/8169725
版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。
最近學(xué)習(xí)Linux操作系統(tǒng),關(guān)于中斷系統(tǒng)調(diào)用和進(jìn)程的級別總是感覺有些模糊的地方,特在此做個小結(jié),整理下思路。
所謂的中斷就是在計算機執(zhí)行程序的過程中,由于出現(xiàn)了某些特殊事情,使得CPU暫停對程序的執(zhí)行,轉(zhuǎn)而去執(zhí)行處理這一事件的程序。等這些特殊事情處理完之后再回去執(zhí)行之前的程序。中斷一般分為三類:1、由計算機硬件異?;蚬收弦鸬闹袛?#xff0c;稱為內(nèi)部異常中斷;2、由程序中執(zhí)行了引起中斷的指令而造成的中斷,稱為軟中斷(這也是和我們將要說明的系統(tǒng)調(diào)用相關(guān)的中斷);3、由外部設(shè)備請求引起的中斷,稱為外部中斷。簡單來說,對中斷的理解就是對一些特殊事情的處理。
與中斷緊密相連的一個概念就是中斷處理程序了。當(dāng)中斷發(fā)生的時候,系統(tǒng)需要去對中斷進(jìn)行處理,對這些中斷的處理是由操作系統(tǒng)內(nèi)核中的特定函數(shù)進(jìn)行的,這些處理中斷的特定的函數(shù)就是我們所說的中斷處理程序了。
另一個與中斷緊密相連的概念就是中斷的優(yōu)先級。中斷的優(yōu)先級說明的是當(dāng)一個中斷正在被處理的時候,處理器能接受的中斷的級別。中斷的優(yōu)先級也表明了中斷需要被處理的緊急程度。每個中斷都有一個對應(yīng)的優(yōu)先級,當(dāng)處理器在處理某一中斷的時候,只有比這個中斷優(yōu)先級高的中斷可以被處理器接受并且被處理。優(yōu)先級比這個當(dāng)前正在被處理的中斷優(yōu)先級要低的中斷將會被忽略。
典型的中斷級如下所示
當(dāng)發(fā)生軟件中斷時,其他所有的中斷都可能發(fā)生并被處理;但當(dāng)發(fā)生磁盤中斷時,就只有時鐘中斷和機器錯誤中斷能被處理了。
在講系統(tǒng)調(diào)用之前,先說下進(jìn)程的執(zhí)行在系統(tǒng)上的兩個級別:用戶級和核心級,也稱為用戶態(tài)和系統(tǒng)態(tài)(user mode ?and kernel mode)。程序的執(zhí)行一般是在用戶態(tài)下執(zhí)行的,但當(dāng)程序需要使用操作系統(tǒng)提供的服務(wù)時,比如說打開某一設(shè)備、創(chuàng)建文件、讀寫文件等,就需要向操作系統(tǒng)發(fā)出調(diào)用服務(wù)的請求,這就是系統(tǒng)調(diào)用。Linux系統(tǒng)有專門的函數(shù)庫來提供這些請求操作系統(tǒng)服務(wù)的入口,這個函數(shù)庫中包含了操作系統(tǒng)說提供的對外服務(wù)的接口。當(dāng)進(jìn)程發(fā)出系統(tǒng)調(diào)用之后,它所處的運行狀態(tài)就會由用戶態(tài)變成核心態(tài)。但這個時候,進(jìn)程本身其實并沒有做什么事情,這個時候是由內(nèi)核在做相應(yīng)的操作,去完成進(jìn)程所提出的這些請求。
系統(tǒng)調(diào)用和中斷的關(guān)系就在于,當(dāng)進(jìn)程發(fā)出系統(tǒng)調(diào)用申請的時候,會產(chǎn)生一個軟件中斷。產(chǎn)生這個軟件中斷以后,系統(tǒng)會去對這個軟中斷進(jìn)行處理,這個時候進(jìn)程就處于核心態(tài)了。
那么用戶態(tài)和核心態(tài)之間的區(qū)別是什么呢?(以下區(qū)別摘至《UNIX操作系統(tǒng)設(shè)計》)
1、用戶態(tài)的進(jìn)程能存取它們自己的指令和數(shù)據(jù),但不能存取內(nèi)核指令和數(shù)據(jù)(或其他進(jìn)程的指令和數(shù)據(jù))。然而,核心態(tài)下的進(jìn)程能夠存取內(nèi)核和用戶地址
2、某些機器指令是特權(quán)指令,在用戶態(tài)下執(zhí)行特權(quán)指令會引起錯誤
對此要理解的一個是,在系統(tǒng)中內(nèi)核并不是作為一個與用戶進(jìn)程平行的估計的進(jìn)程的集合,內(nèi)核是為用戶進(jìn)程運行的。
如何去理解上面所說的區(qū)別,特別是區(qū)別1呢?真正理解這點,需要對進(jìn)程在內(nèi)存中的表示有個大致的理解。
每個程序需要被裝入(全部或部分)裝入內(nèi)存后才能開始運行,在32位機器中,每個進(jìn)程都有4G的虛擬地址空間。但是對這4G的空間并不是全部都可以被進(jìn)程使用的,在Linux中,對這4G的空間的大致劃分如下
因此,從原則上來說,在進(jìn)程中用戶能使用的虛擬地址空間是只有3G的。正常情況下,用戶程序在用戶態(tài)運行的時候,只能訪問在這3G范圍內(nèi)的地址(當(dāng)然也不是所有地址都能訪問)。當(dāng)進(jìn)程由于系統(tǒng)調(diào)用而進(jìn)入核心態(tài)時,這時系統(tǒng)內(nèi)核會執(zhí)行相應(yīng)的操作,它能訪問自己1G的地址空間,同時也能訪問3G的用戶地址空間。而用戶進(jìn)程的指令的數(shù)據(jù)是存在與那3G的地址空間中的。當(dāng)然還有進(jìn)程的棧等部分。
細(xì)分來說的話,一個進(jìn)程在內(nèi)存中一般包含以下部分,數(shù)據(jù)段、指令段、運行時堆、棧等。示意圖如下
內(nèi)核自己的棧這在最上層的1G的地址空間內(nèi),這是只能由內(nèi)核訪問的部分。
?
在說進(jìn)程調(diào)度之前,首先整理下進(jìn)程可能的各種狀態(tài)。首先我們知道進(jìn)程的運行狀態(tài)是分為核心態(tài)和用戶態(tài)。其他的進(jìn)程狀態(tài)包括如下
進(jìn)程未被執(zhí)行,但出于就緒狀態(tài),只要內(nèi)核調(diào)度它,即可執(zhí)行
進(jìn)程正在睡眠中并且存在主存中
進(jìn)程處于就緒狀態(tài),但處在二級存儲器中
進(jìn)程在睡眠中,且在二級存儲器中
進(jìn)程執(zhí)行完核心態(tài)的操作,正要返回用戶態(tài)時,內(nèi)核做了進(jìn)程調(diào)度,切換了上下文
進(jìn)程剛被創(chuàng)建
進(jìn)程調(diào)用了exit,處于僵死狀態(tài)
進(jìn)程之間的狀態(tài)轉(zhuǎn)換示意圖如下,箭頭指明了轉(zhuǎn)換的方向
進(jìn)程的各種狀態(tài)的轉(zhuǎn)換比較復(fù)雜,這里主要關(guān)注進(jìn)程的兩個運行狀態(tài)、睡眠以及從就緒到運行的轉(zhuǎn)換
從示意圖中可以看出,當(dāng)發(fā)生中斷或者系統(tǒng)調(diào)用時,進(jìn)程由用戶態(tài)轉(zhuǎn)成核心態(tài)。但進(jìn)程在核心態(tài)運行時,是不能被搶占的,因此只有當(dāng)進(jìn)程由核心態(tài)進(jìn)入睡眠狀態(tài)時,或者進(jìn)程處于用戶態(tài)時,內(nèi)核才允許做進(jìn)程調(diào)度,切換上下文。而處于就緒狀態(tài)的進(jìn)程當(dāng)被內(nèi)核調(diào)度開始運行的時候,首先是進(jìn)入核心態(tài)的。
那么為什么,進(jìn)程在核心態(tài)運行的時候,不允許做進(jìn)程調(diào)度呢?因為在核心態(tài)運行的時候,需要訪問一些全局核心數(shù)據(jù)結(jié)構(gòu)中的信息。如果運行在核心態(tài)時的進(jìn)程調(diào)度,那么會改變內(nèi)核運行時的進(jìn)程上下文,而這些不同的進(jìn)程上下文對同一個核心數(shù)據(jù)可能會有不同的操作要求,這樣將有可能會破壞全局核心數(shù)據(jù)結(jié)構(gòu)中的信息。為了保證內(nèi)核核心數(shù)據(jù)的一致性,當(dāng)進(jìn)程處于核心態(tài)時,是不允許進(jìn)行上下文切換的。
這就涉及到另一個問題,中斷是在任何時刻都能發(fā)生的,并且對中斷的處理也可能影響內(nèi)核數(shù)據(jù)的一致性。那么,但進(jìn)程在核心態(tài)運行時,對于發(fā)生中斷的情況又如何保證內(nèi)核數(shù)據(jù)的一致性呢?解決的方法大致分為兩類,一種是簡單地在核心態(tài)時,禁止所有的中斷,但這樣會降低對中斷的響應(yīng)速度;另一種方法是設(shè)立臨界區(qū),找出操作語句中可能會導(dǎo)致內(nèi)核數(shù)據(jù)不一致的地方,然后將這部分設(shè)為臨界區(qū)。但CPU執(zhí)行臨界區(qū)代碼時,把CPU的執(zhí)行級別提高,這樣就可以屏蔽掉很多的中斷,從而保證數(shù)據(jù)的一致性了。一般,為了保證系統(tǒng)的性能,臨界區(qū)都很小,并且不會經(jīng)常出現(xiàn)。
【作者】張昺華 【出處】http://www.cnblogs.com/sky-heaven/ 【博客園】 http://www.cnblogs.com/sky-heaven/ 【新浪博客】 http://blog.sina.com.cn/u/2049150530 【知乎】 http://www.zhihu.com/people/zhang-bing-hua 【我的作品---旋轉(zhuǎn)倒立擺】 http://v.youku.com/v_show/id_XODM5NDAzNjQw.html?spm=a2hzp.8253869.0.0&from=y1.7-2 【我的作品---自平衡自動循跡車】 http://v.youku.com/v_show/id_XODM5MzYyNTIw.html?spm=a2hzp.8253869.0.0&from=y1.7-2 【新浪微博】 張昺華--sky 【twitter】 @sky2030_ 【facebook】 張昺華 zhangbinghua 本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利.總結(jié)
以上是生活随笔為你收集整理的Linux系统的中断、系统调用和调度概述【转】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LeetCode【217. Contai
- 下一篇: centos6下时间同步(ntp)操作