版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、華南理工大學(xué)高級操作系統(tǒng)復(fù)習(xí)資料Ch 1.【linux內(nèi)核特點(diǎn)】Linux是單內(nèi)核,但汲取了微內(nèi)核的精華,其特點(diǎn)如下:(1) 支持動態(tài)加載內(nèi)核模塊,可動態(tài)的卸除和加載部分內(nèi)核代碼;(2) 支持對稱多處理機(jī)制(SMP);(3) 內(nèi)核可搶占,允許內(nèi)核執(zhí)行高優(yōu)先級的任務(wù);(4) 獨(dú)特的線程實(shí)現(xiàn),內(nèi)核不區(qū)分線程和其他一般進(jìn)程,一樣都是task;(5) 設(shè)備管理中提供具有設(shè)備類的面向?qū)ο蟮脑O(shè)備模型、熱插拔事件、以及用戶空間的設(shè)備文件系統(tǒng);(6) 拋棄了Unix中拙劣的stream特性,忽略了一些實(shí)際上已經(jīng)不會使用的過時標(biāo)準(zhǔn);(7) 自由,公開開發(fā)模型自由務(wù)實(shí)發(fā)展?!締蝺?nèi)核】單內(nèi)核就是把它從整體上作為一個
2、單獨(dú)的大過程來實(shí)現(xiàn),并同時運(yùn)行在一個單獨(dú)的地址空間。即所有內(nèi)核服務(wù)都在一個大的內(nèi)核空間中運(yùn)行,內(nèi)核可以直接調(diào)用函數(shù)。Linux是一個單內(nèi)核,它運(yùn)行在單獨(dú)的內(nèi)核地址空間。單內(nèi)核模式具有簡單和高性能的特點(diǎn)。【內(nèi)核版本號】從版本號為偶數(shù),則為穩(wěn)定版;否則為開發(fā)版。Ch 2.【LINUX內(nèi)核開發(fā)特點(diǎn)】(1) 不能訪問C庫,對內(nèi)核而言C庫太大了,但大部分常用C庫函數(shù)在內(nèi)核中都有實(shí)現(xiàn);(2) 必須使用GNU C;(3) 缺乏內(nèi)存保護(hù)機(jī)制,內(nèi)核中的內(nèi)存都不分頁;(4) 浮點(diǎn)數(shù)很難使用,復(fù)雜繁瑣,原則是不要在內(nèi)核中使用浮點(diǎn)數(shù);(5) 只有容積很小且定長的堆棧;(6) 內(nèi)核支持異步中斷、搶占和SMP,所以容易出
3、現(xiàn)競爭條件,要求時刻注意同步和并發(fā),設(shè)置同步機(jī)制保證不出現(xiàn)競爭條件,通過自旋鎖和信號量解決競爭條件;(7) 要注重可移植性。*【內(nèi)聯(lián)函數(shù)】工作方式:函數(shù)會在它所調(diào)用的位置上展開,可以消除函數(shù)調(diào)用和返回所帶來的開銷(寄存器儲存與恢復(fù))。但這樣會使代碼變長,占用更多的內(nèi)存空間或者指令緩存。通常對時間要求高、長度較短的函數(shù)定義為內(nèi)聯(lián)函數(shù)。定義方法:以static為關(guān)鍵字,用inline限定,例如:Ch 3.【進(jìn)程、線程、內(nèi)核線程】進(jìn)程:一個進(jìn)程就是處于執(zhí)行期的程序以及它所包含的資源的總稱。這些資源包括:打開的文件、掛起的信號、內(nèi)核內(nèi)部數(shù)據(jù)、處理器狀態(tài)、地址空間及一個或多個執(zhí)行線程等。線程:線程是在進(jìn)
4、程中活動的對象,它為共享一個地址空間的程序提供多個執(zhí)行線索,它可以共享打開的文件和其他資源。內(nèi)核調(diào)度的對象是線程而不是進(jìn)程,每個線程擁有一個獨(dú)立的程序計(jì)數(shù)器、進(jìn)程棧和一組進(jìn)程寄存器。在Linux中每個線程和進(jìn)程一樣有唯一(唯一隸屬自己)的task_struck,在內(nèi)核看來與一般進(jìn)程沒有什么區(qū)別,當(dāng)進(jìn)程間選擇性的共享地址空間時它可視為線程。內(nèi)核線程:是標(biāo)準(zhǔn)的進(jìn)程,只存在于內(nèi)核空間;沒有地址空間;只能由其他內(nèi)核線程創(chuàng)建;可以被調(diào)度,也可以被搶占?!具M(jìn)程和線程的區(qū)別】(1) 進(jìn)程有獨(dú)立地址空間,線程沒有(2) 進(jìn)程是處于執(zhí)行期的代碼以及它包含的資源的總稱,線程是進(jìn)程中活動的對象。(3) 進(jìn)程是資源管
5、理的最小單位,線程是程序執(zhí)行的最小單位,內(nèi)核調(diào)度的對象是線程而不是進(jìn)程?!揪€程的實(shí)現(xiàn)】Linux實(shí)現(xiàn)線程的機(jī)制非常獨(dú)特,內(nèi)核把所有的線程都當(dāng)做進(jìn)程來實(shí)現(xiàn),線程只被視為一個與其它進(jìn)程共享某些資源的進(jìn)程。每個線程擁有獨(dú)立的程序計(jì)數(shù)器、進(jìn)程棧和一組進(jìn)程寄存器,并且和進(jìn)程一樣擁有唯一隸屬于自己的task_struct?!具M(jìn)程狀態(tài)】(1) TASK_RUNNING(運(yùn)行)進(jìn)程是可執(zhí)行的。或者正在執(zhí)行,或者在等待隊(duì)列中(2) TASK_INTERRUPTIBLE(可中斷)進(jìn)程正在睡眠,等待某些條件的達(dá)成。(3) TASK_INTERRUPTIBLE(不可中斷)接收到信號也不會被喚醒后者投入運(yùn)行(4) TA
6、SK_TRACED被其他進(jìn)程跟蹤(5) TASK_STOPPED進(jìn)程停止執(zhí)行【進(jìn)程狀態(tài)轉(zhuǎn)換圖】*【進(jìn)程描述符和Task Structure】內(nèi)核把所有進(jìn)程放在一個雙向鏈表中-task list:圖中的每一個節(jié)點(diǎn)都是一個很大的數(shù)據(jù)結(jié)構(gòu)task_struct - 進(jìn)程描述符,其包含:進(jìn)程狀態(tài)、進(jìn)程的地址空間、PID、指向父進(jìn)程的指針、打開的文件。【進(jìn)程上下文】系統(tǒng)提供給進(jìn)程的處于動態(tài)變化的運(yùn)行環(huán)境總和稱為進(jìn)程上下文,這些資源包括CPU的所有寄存器中的值、進(jìn)程的狀態(tài)以及堆棧中的內(nèi)容,當(dāng)前進(jìn)程上下文均保存在進(jìn)程的任務(wù)數(shù)結(jié)構(gòu)中。程序在用戶空間運(yùn)行,它執(zhí)行了系統(tǒng)調(diào)用或者觸發(fā)了某個異常,它就陷入了內(nèi)核空間,
7、此時我們稱“內(nèi)核代表進(jìn)程執(zhí)行”并處于進(jìn)程上下文。進(jìn)程沒有其他進(jìn)入內(nèi)核空間的方法。在進(jìn)程上下文中,內(nèi)核可以休眠,并且可以被搶占?!綾urrent宏】在Linux平臺下,每一個進(jìn)程都有一個task_struct數(shù)據(jù)結(jié)構(gòu),用來存儲該進(jìn)程的相關(guān)信息。在內(nèi)核模塊中,可以通過調(diào)用current來獲取當(dāng)前進(jìn)程的task_struct數(shù)據(jù)結(jié)構(gòu)。 *【進(jìn)程家族樹】所有的進(jìn)程都是init 進(jìn)程的子孫,其PID是 1,進(jìn)程只有一個父母 ,在進(jìn)程的 task_struct中的parent表示,進(jìn)程可以有0個以上的子女,在進(jìn)程的 task_struct中的children表示。獲得父親代碼:訪問子進(jìn)程代碼:下一個/上一
8、個進(jìn)程:進(jìn)程遍歷: 【進(jìn)程創(chuàng)建的步驟】兩個主要步驟:(1) 創(chuàng)建一個子進(jìn)程即復(fù)制當(dāng)前的任務(wù) fork() 函數(shù)- 新進(jìn)程與其父進(jìn)程的區(qū)別僅在于PID, PPID以及特定的資源- 當(dāng)進(jìn)程執(zhí)行一個系統(tǒng)調(diào)用或觸發(fā)一個例外時,進(jìn)入內(nèi)核空間- 進(jìn)程除此之外再沒有其他方式進(jìn)入內(nèi)核空間(2) 將一個程序裝入地址空間并執(zhí)行 exec() - 內(nèi)核線程是標(biāo)準(zhǔn)的進(jìn)程,只存在于 內(nèi)核空間- 內(nèi)核線程沒有地址空間- 內(nèi)核線程只能由其他內(nèi)核線程創(chuàng)建l Linux通過clone()系統(tǒng)調(diào)用實(shí)現(xiàn)fork(),由clone()去調(diào)用do_fork(),do_fork()調(diào)用copy_process()函數(shù)l Vfork()與
9、fork區(qū)別在于,創(chuàng)建完成后父進(jìn)程阻塞,直至子進(jìn)程結(jié)束或執(zhí)行exec() 【寫時拷貝】寫時拷貝是指在需要寫入的時候才進(jìn)行資源復(fù)制,是一種可以推遲甚至免除拷貝數(shù)據(jù)的技術(shù)。Linux的fork()使用寫時拷貝數(shù)據(jù)實(shí)現(xiàn),創(chuàng)建子進(jìn)程時不需要立即給子進(jìn)程拷貝數(shù)據(jù),而是讓父子進(jìn)程以只讀的方式共享沒有修改的數(shù)據(jù)和空間,而當(dāng)父子進(jìn)程之一修改數(shù)據(jù)時則進(jìn)行拷貝?!具M(jìn)程的終結(jié)】結(jié)束的起因:進(jìn)程結(jié)束其工作,或者收到一個信號,或者發(fā)生了它自己不能處理的異常。結(jié)束過程:進(jìn)程開始執(zhí)行exit() 函數(shù)- 釋放進(jìn)程的地址空間- 釋放進(jìn)程使用的資源- 給其父進(jìn)程發(fā)送一個信號,并標(biāo)示自己的狀態(tài)為TASK_ZOMBIE- 調(diào)用調(diào)度
10、程序,執(zhí)行其他進(jìn)程l 進(jìn)程結(jié)束后還保留內(nèi)核棧、thread_info結(jié)構(gòu)、task_struct結(jié)構(gòu)。存在的唯一目的就是向父進(jìn)程提供信息。父進(jìn)程檢索到信息后,或通知內(nèi)核那是無關(guān)信息,內(nèi)存釋放。*【孤兒進(jìn)程】其父進(jìn)程已經(jīng)終止,系統(tǒng)試圖給子進(jìn)程安排一個父進(jìn)程,若失敗,由init進(jìn)程收養(yǎng)。孤兒進(jìn)程組:該組中每個成員的父進(jìn)程要么是該組的一個成員,要么不是該組所屬會話的成員。一個進(jìn)程組不是孤兒進(jìn)程組的條件是:該組中有一個進(jìn)程,其父進(jìn)程在屬于同一會話中的另一個組中。Ch 4.【進(jìn)程時間片】進(jìn)程時間片是指,進(jìn)程在被搶占前所能持續(xù)運(yùn)行的CPU時間,它是一個有系統(tǒng)調(diào)度策略設(shè)定的數(shù)值。Linux采用了預(yù)加載調(diào)度策
11、略,每個進(jìn)程只運(yùn)行很短的時間:200毫秒;同時Linux調(diào)度程序還能根據(jù)進(jìn)程的優(yōu)先級動態(tài)調(diào)整分配給它的時間片,來保證高優(yōu)先級的進(jìn)程執(zhí)行的高頻率和長時間。一個進(jìn)程不一定一次必須用完自己的時間片。當(dāng)進(jìn)程的時間片用完時,進(jìn)程不再執(zhí)行,直到其他進(jìn)程也使用完了自己的時間片。 【進(jìn)程優(yōu)先級】Nice值:從-20到19,值越小優(yōu)先級越高。實(shí)時優(yōu)先級:從0到99,值越大優(yōu)先級越高。任何實(shí)時進(jìn)程的優(yōu)先級都高于普通進(jìn)程?!綜FS思想】允許每個進(jìn)程運(yùn)行一段時間、循環(huán)輪轉(zhuǎn)、選擇運(yùn)行最少的進(jìn)程作為下一個運(yùn)行進(jìn)程。【Linux調(diào)度實(shí)現(xiàn)四個主要部分】時間記賬、進(jìn)程選擇、調(diào)度器入口、睡眠和喚醒【O(1)調(diào)度器】所有的算法在規(guī)
12、定的時間內(nèi)運(yùn)行完,其數(shù)據(jù)結(jié)構(gòu):運(yùn)行隊(duì)列和優(yōu)先級矩陣。執(zhí)行調(diào)度時,速度很快新增的特性:改善了SMP可擴(kuò)展性,包括NUMA.較好的處理器親和力。SMT 調(diào)度.【linux2.6 調(diào)度程序的目標(biāo)】有效性:完成盡可能多的工作;交互性:盡快響應(yīng)用戶;公平性:不允許任何進(jìn)程饑餓。(1) 充分實(shí)現(xiàn)O(1)調(diào)度。不管有多少進(jìn)程,新調(diào)度程序采用的每個算法都能在恒定時間內(nèi)完成;(2) 全面實(shí)現(xiàn)SMP的可擴(kuò)展性。每個處理器擁有自己的鎖和自己的可執(zhí)行隊(duì)列;(3) 強(qiáng)化SMP的親和力。盡量將相關(guān)一組任務(wù)分配給一個CPU進(jìn)行連續(xù)執(zhí)行;(4) 加強(qiáng)交互性能。即使在系統(tǒng)處于相當(dāng)負(fù)載的情況下,也能保證系統(tǒng)的相應(yīng),并立即調(diào)度交互
13、式進(jìn)程;(5) 保證公平。在合理設(shè)定的時間范圍內(nèi),沒有進(jìn)程會處于饑餓狀態(tài),也沒有進(jìn)程能不公平的得到大量時間片;(6) 雖然常見的優(yōu)化情況是系統(tǒng)中只有1-2個可運(yùn)行進(jìn)程,但是優(yōu)化它也完全有能力擴(kuò)展到具有多處理器每個處理器上運(yùn)行多個進(jìn)程的系統(tǒng)中?!具\(yùn)行隊(duì)列】l 給定處理器上可執(zhí)行進(jìn)程的鏈表.l 對運(yùn)行隊(duì)列進(jìn)行操作前要先鎖住.運(yùn)行隊(duì)列中的數(shù)據(jù):用于解決并發(fā)問題的鎖.指向當(dāng)前任務(wù)和空任務(wù)的指針.優(yōu)先級數(shù)組.統(tǒng)計(jì)信息【優(yōu)先級數(shù)組】維護(hù)兩個優(yōu)先級矩陣:活躍的和過期的矩陣。過期的:所有用完了時間片的進(jìn)程實(shí)際的:沒有用完時間片的進(jìn)程l 當(dāng)一個進(jìn)程用完了時間片時,重新計(jì)算其時間片,并放入到過期隊(duì)列中l(wèi) 當(dāng)實(shí)際進(jìn)
14、程隊(duì)列為空時,交換過期隊(duì)列和實(shí)際隊(duì)列【睡眠和喚醒】睡眠:置標(biāo)志為睡眠, 把自己放于等待隊(duì)列, 把自己從運(yùn)行隊(duì)列中刪除,調(diào)用schedule() 選擇新進(jìn)程執(zhí)行。喚醒:置標(biāo)志為可運(yùn)行,從等待隊(duì)列中刪除,加到運(yùn)行隊(duì)列的后面?!救蝿?wù)調(diào)度過程】【優(yōu)先級和時間片的計(jì)算】動態(tài)優(yōu)先級用于計(jì)算優(yōu)先級:l nice+進(jìn)程交互性的獎勵或罰分l 為了確定一個進(jìn)程是否是交互性的, Linux記錄了一個進(jìn)程用于休眠和用于執(zhí)行的時間(0-MAX_SLEEP_AVG,默認(rèn)10ms)。一個進(jìn)程從休眠恢復(fù)到執(zhí)行時,增加;運(yùn)行一段時間后會減小。靜態(tài)優(yōu)先級用于計(jì)算時間片: l 進(jìn)程創(chuàng)建時,子進(jìn)程與父進(jìn)程均分父進(jìn)程剩余的時間片.l
15、任務(wù)的時間片用完時,基于任務(wù)的靜態(tài)優(yōu)先級重新計(jì)算時間片。 【負(fù)載平衡程序的操作步驟】Linux為對稱多處理器(SMP)系統(tǒng)中的每個處理器準(zhǔn)備了單獨(dú)的可執(zhí)行隊(duì)列和鎖,而負(fù)載平衡程序則負(fù)責(zé)保證這些可執(zhí)行隊(duì)列之間的負(fù)載處于均衡狀態(tài)。負(fù)載平衡程序由load_balance()函數(shù)實(shí)現(xiàn),它所完成的操作步驟歸結(jié)如下:(1) 找最繁忙的可執(zhí)行運(yùn)行隊(duì)列;(2) 從最繁忙的隊(duì)列中選擇一個優(yōu)先級數(shù)組(過期的優(yōu)先)以便抽取進(jìn)程;(3) 選擇含有進(jìn)程并且優(yōu)先級最高(值最?。┑逆湵?;(4) 選擇一個不是正在運(yùn)行的且不在高速緩沖的進(jìn)程,可移動的進(jìn)程抽取;(5) 重復(fù)上述步驟,直至平衡?!菊{(diào)度程序狀態(tài)之間的關(guān)系】【進(jìn)程搶占
16、的時機(jī)】l 當(dāng)一個進(jìn)程的優(yōu)先級高于當(dāng)前正在運(yùn)行的進(jìn)程的優(yōu)先級l 當(dāng)一個進(jìn)程的時間片為0.【內(nèi)核搶占/搶占】內(nèi)核搶占:當(dāng)進(jìn)程位于內(nèi)核空間,若有一個更高優(yōu)先級的任務(wù)出現(xiàn)時,可以將當(dāng)前任務(wù)掛起,切換去執(zhí)行優(yōu)先級更高的進(jìn)程,而這個強(qiáng)制掛起的動作叫搶占??蓳屨嫉那疤嵝枰_保重新調(diào)度是安全的,即當(dāng)前的任務(wù)沒有持有鎖,在這種情況下內(nèi)核可以在任何時間搶占正在執(zhí)行的任務(wù)。2.6版本后的Linux內(nèi)核是可搶占式內(nèi)核,具有上述允許內(nèi)核優(yōu)先執(zhí)行高優(yōu)先級任務(wù)的能力?!居脩魮屨及l(fā)生在什么情況】在內(nèi)核即將返回用戶空間的時候,如果need_resched標(biāo)志被設(shè)置,會導(dǎo)致schedule()被調(diào)用,此時就會發(fā)生用戶搶占:1)
17、從系統(tǒng)調(diào)用返回用戶空間; 2)從中斷處理程序返回用戶空間?!緝?nèi)核搶占發(fā)生在什么情況】(1) 中斷處理程序正在執(zhí)行,且返回內(nèi)核空間之前;(2) 內(nèi)核代碼再一次具有可搶占性的時候(preemt_count重新為0);(3) 內(nèi)核中的任務(wù)顯示的調(diào)用schedule();(處于核心態(tài)的任務(wù)直接調(diào)用schedule())(4) 內(nèi)核中的任務(wù)阻塞時(這同樣也會導(dǎo)致調(diào)用schedule())?!旧舷挛那袚Q】從一個可執(zhí)行的進(jìn)程切換到另一個可執(zhí)行的進(jìn)程。由context_switch()函數(shù)負(fù)責(zé)完成,它完成了兩項(xiàng)基本工作:(1) 調(diào)用 switch_mm(),把虛擬內(nèi)存從上一個進(jìn)程影射切換到新進(jìn)程(2) 調(diào)用
18、switch_to(),從上一個進(jìn)程的處理器狀態(tài)切換到新進(jìn)程的處理器狀態(tài)中,包括保存、恢復(fù)、棧信息和寄存器信息。【軟實(shí)時】內(nèi)核調(diào)度進(jìn)程,盡力使進(jìn)程在它的限定時間到來前運(yùn)行,但內(nèi)核不保證總能滿足這些進(jìn)程的需求。【SCHED_FIFO 與SCHED_RR 實(shí)時調(diào)度的區(qū)別】SCHED_FIFO: 實(shí)現(xiàn)了一種簡單的,先入先出的調(diào)度算法,它不使用時間片。SCHED_FIFO級的進(jìn)程會比任何SCHED_NORMAL級的進(jìn)程都先得到調(diào)度;SCHED_FIFO級進(jìn)程不基于時間片,只要它處于可執(zhí)行狀態(tài),就會一直執(zhí)行,直到它自己受阻塞或顯示的釋放處理器為止。只有較高級的SCHED_FIFO或者SCHED_RR任務(wù)
19、才能搶占SCHED_FIFO任務(wù)。SCHED_RR: 與SCHED_FIFO大體相同,但是受時間片的限制。SCHED_RR級的進(jìn)程在耗盡事先分配給它的時間片后就不能再接著執(zhí)行了,也就是說,SCHED_RR是帶有時間片的SCHED_FIFO,這是一種實(shí)時輪流調(diào)度算法?!九c調(diào)度相關(guān)的系統(tǒng)調(diào)用】l 調(diào)度策略和優(yōu)先級相關(guān)的系統(tǒng)調(diào)用l 處理器綁定系統(tǒng)調(diào)用l 放棄處理器時間Ch 5.【系統(tǒng)調(diào)用作為進(jìn)程與硬件中間層的作用】(1) 系統(tǒng)調(diào)用為用戶空間提供了一種硬件的抽象接口;(2) 系統(tǒng)調(diào)用保證了系統(tǒng)的穩(wěn)定和安全;(3) 系統(tǒng)調(diào)用是用戶空間訪問內(nèi)核的唯一手段,除異常和陷入外,他們是內(nèi)核唯一的合法入口。每個進(jìn)程
20、都運(yùn)行在虛擬系統(tǒng)中,在用戶空間和系統(tǒng)的其余部分提供這樣一層公共接口,也是出于這種考慮。 【系統(tǒng)調(diào)用與C庫函數(shù)的作用(聯(lián)系)】l API是應(yīng)用程序接口 - 應(yīng)用針對API編程,不直接使用系統(tǒng)調(diào)用. - API定義了應(yīng)用程序使用的一組程序接口. l POSIX 標(biāo)準(zhǔn). Linux 與POSIX完全兼容.l Linux中的系統(tǒng)調(diào)用接口,與大多數(shù)Unix系統(tǒng)類似,以C 庫的形式提供【系統(tǒng)調(diào)用】所有的操作系統(tǒng)在其內(nèi)核里都有一些內(nèi)建的接口函數(shù),這些函數(shù)可以用來完成一些系統(tǒng)級別的功能。Linux系統(tǒng)使用的這樣的函數(shù)叫做“系統(tǒng)調(diào)用”,英文是systemcall。這些函數(shù)代表了從用戶空間到內(nèi)核空間的一種轉(zhuǎn)換,應(yīng)
21、用程序通過這些接口函數(shù)訪問硬件設(shè)備和其他的操作系統(tǒng)資源。Linux中,系統(tǒng)調(diào)用時用戶空間訪問內(nèi)核的唯一手段,除異常和陷入之外,它們是內(nèi)核唯一的合法入口?!居脩艨臻g間接執(zhí)行系統(tǒng)調(diào)用】由于不允許用戶空間的應(yīng)用直接訪問內(nèi)核代碼,應(yīng)用必須通知內(nèi)核,它想執(zhí)行系統(tǒng)調(diào)用,使系統(tǒng)切換到內(nèi)核方式。通知的機(jī)制內(nèi)核是一個軟中斷:產(chǎn)生一個異常,系統(tǒng)切換到內(nèi)核模式,執(zhí)行異常處理程序,即系統(tǒng)調(diào)用處理程序。 - 在x86上,定義的軟中斷是函數(shù)system_call(). - x86處理器增加了一個特性sysenter. l 應(yīng)用必須使用系統(tǒng)調(diào)用號進(jìn)入內(nèi)核空間。在x86中,使用eax寄存器把調(diào)用號傳遞給內(nèi)核。 l syste
22、m_call()檢查調(diào)用號,如合法,調(diào)用指定的系統(tǒng)調(diào)用?!緟?shù)驗(yàn)證 】l 系統(tǒng)調(diào)用必須保證其所有參數(shù)是合法的,例如:- 指針指向的內(nèi)存區(qū)域?qū)儆谟脩艨臻g- 指針指向的內(nèi)存區(qū)域在進(jìn)程的地址空間里- 如果是讀(寫/執(zhí)行),該內(nèi)存應(yīng)該標(biāo)記為可讀(寫/執(zhí)行)l 兩種方法完成必須的檢查和內(nèi)核空間與用戶空間之間的數(shù)據(jù)拷貝: - 向用戶空間寫數(shù)據(jù), 可用方法 copy_to_user(目標(biāo)地址,源地址,要拷貝的數(shù)量)- 從用戶空間讀數(shù)據(jù),可用方法copy_from_user(目標(biāo)地址,源地址,要拷貝的數(shù)量)- 讀寫權(quán)限檢查:suser() 和 capable() 【綁定一個系統(tǒng)調(diào)用的步驟】(1) 首先在系統(tǒng)調(diào)
23、用表的最后加入一個表項(xiàng)。 (2) 對于每一種支持的體系結(jié)構(gòu),系統(tǒng)調(diào)用號必須定義在 . (3) 系統(tǒng)調(diào)用必須被編譯進(jìn)內(nèi)核映像【從用戶空間訪問系統(tǒng)調(diào)用】Linux 提供了一組宏,用于直接訪問系統(tǒng)調(diào)用。它設(shè)置寄存器內(nèi)容,并執(zhí)行trap指令。這些宏_syscalln(), 這里n:0-6?!緦?shí)現(xiàn)一個新的系統(tǒng)調(diào)用的好處】(1) 系統(tǒng)調(diào)用容易使用容易實(shí)現(xiàn)。(2) 系統(tǒng)調(diào)用的性能在Linux中非常快。【實(shí)現(xiàn)一個新的系統(tǒng)調(diào)用的缺點(diǎn)】(1) 系統(tǒng)調(diào)用號需要官方授權(quán)給你。 (2) 系統(tǒng)調(diào)用一旦進(jìn)入穩(wěn)定的內(nèi)核,其接口就不能再改變,否則會影響用戶空間的應(yīng)用.(3) 需要將系統(tǒng)調(diào)用分別注冊到每個需要支持的體系結(jié)構(gòu)。(4
24、) 系統(tǒng)調(diào)用在腳本中不宜使用,不能直接從文件系統(tǒng)訪問(5) 如果僅僅進(jìn)行簡單的信息交換,系統(tǒng)調(diào)用就大材小用了【增加Linux系統(tǒng)調(diào)用的的注意事項(xiàng)】(1) 定義系統(tǒng)調(diào)用的目的. (2) 系統(tǒng)調(diào)用的參數(shù)、返回值以及錯誤碼. (3) 設(shè)計(jì)的接口盡量為將來考慮 (4) 注意可移植性和健壯性Ch 7.【中斷上下文】當(dāng)執(zhí)行一個中斷處理程序時或下半部時,內(nèi)核處于中斷上下文。硬件通過觸發(fā)信號,導(dǎo)致內(nèi)核調(diào)用中斷處理程序,進(jìn)入內(nèi)核空間。這個過程中,硬件的一些變量和參數(shù)也要傳遞傳遞給內(nèi)核,內(nèi)核根據(jù)這些參數(shù)進(jìn)行中斷處理。所謂“中斷上下文”,其實(shí)也可以看作就是硬件傳遞過來的這些參數(shù)和內(nèi)核需要保存的一些其他環(huán)境。中斷上下
25、文中執(zhí)行的代碼不可阻塞?!局袛鄼C(jī)制】當(dāng)硬件處理I/O等操作時,內(nèi)核在此期間處理其他事物而不等待硬件完成,當(dāng)硬件直至完成了請求的操作后,再通知內(nèi)核回過頭來處理,這就是中斷機(jī)制?!局袛嗵幚沓绦颉恐袛嗵幚沓绦蚺c其他內(nèi)核函數(shù)的真正區(qū)別在于,中斷處理程序是被內(nèi)核調(diào)用來響應(yīng)中斷的,而它們運(yùn)行于我們稱之為中斷上下文的特殊上下文中。中斷處理程序是上半部,只有嚴(yán)格時限工作,執(zhí)行期間所有中斷被禁止?!居|發(fā)軟中斷】l 一個注冊的軟中斷必須在被標(biāo)記后才會執(zhí)行,這被稱作觸發(fā)軟中斷(raising the softirq)?!緋roc文件系統(tǒng)】proc文件系統(tǒng)是一個偽文件系統(tǒng),它只存在內(nèi)存當(dāng)中,而不占用外存空間。它以文件
26、系統(tǒng)的方式為訪問系統(tǒng)內(nèi)核數(shù)據(jù)的操作提供接口。用戶和應(yīng)用程序可以通過proc得到系統(tǒng)的信息,并可以改變內(nèi)核的某些參數(shù)。由于系統(tǒng)的信息,如進(jìn)程,是動態(tài)改變的,所以用戶或應(yīng)用程序讀取proc文件時,proc文件系統(tǒng)是動態(tài)從系統(tǒng)內(nèi)核讀出所需信息并提交的?!镜怯浿袛嗵幚沓绦颉孔裕篟equest_irq()可能會睡眠,所以不能在中斷上下文中調(diào)用釋放:不是共線的中斷線,釋放后同時禁用。iqrflags:(1) IRQF_DISABLED:快速中斷處理程序,禁止所有中斷,時鐘中斷使用(2) IRQF_SAMPLE_RANDOM:對內(nèi)核熵池有貢獻(xiàn)(3) IRQF_TIMER:系統(tǒng)定時器專用(4) IRQF_S
27、HARED:共享中斷線【編寫中斷處理程序】irq: 中斷號dev_id: 區(qū)分共享中斷線的多個設(shè)備regs: 保存中斷前的處理器的寄存器和狀態(tài)irqreturn_t:IRQ_NONE(中斷設(shè)備不是制定產(chǎn)生源), IRQ_HANDLED(確實(shí)是產(chǎn)生設(shè)備的中斷)【共享的處理程序】request_irq()中必須設(shè)置SA_SHIRQdev_id在每一個登記的處理程序中唯一處理程序必須有能力區(qū)分硬件是否產(chǎn)生了中斷【中斷處理的實(shí)現(xiàn)】【中斷控制】禁止和允許中斷:local_irq_disable()local_irq_enable()local_irq_save()local_irq_restore()禁
28、止特定的中斷線void disable_irq(unsigned int irq);void disable_irq_nosync(unsigned int irq);void enable_irq(unsigned int irq);void synchronize_irq(unsigned int irq);中斷系統(tǒng)的狀態(tài)in_interrupt ()in_irq()Ch 8.【中斷上下文】l 不能睡眠。l 保護(hù)臨界區(qū),不能使用互斥體,因?yàn)樗鼈円苍S導(dǎo)致睡眠。應(yīng)用自旋鎖,只有真正需要的時候才用。l 不能與用戶空間直接交互數(shù)據(jù),因?yàn)樗鼈兘?jīng)由進(jìn)程上下文與用戶空間建立連接。這也是為什么中斷處理函數(shù)
29、不能睡眠的第2個理由:調(diào)度器工作于進(jìn)程之間,如果中斷處理函數(shù)睡眠并被調(diào)度出去,它們返回不到運(yùn)行隊(duì)列l(wèi) 一方面需要快速地出來,另一方面又需要完成它的工作。為了規(guī)避這種沖突,中斷處理函數(shù)通常被分成2個部分。l 不必是可重入的。當(dāng)某中斷被執(zhí)行時,在它返回前,相應(yīng)的IRQ被禁止。因此,與進(jìn)程上下文不同,同一中斷處理函數(shù)的不同實(shí)例不可能同時運(yùn)行在多個處理器上。l 可被更高優(yōu)先級IRQ中斷處理函數(shù)打斷。若請求內(nèi)核將中斷處理函數(shù)作為快中斷,此處理器所有中斷被禁止。l 函數(shù)中可以檢查in_interrupt()的返回值以查看自身是否位于中斷上下文l 中斷處理程序異步執(zhí)行l(wèi) 下半部執(zhí)行的關(guān)鍵在于它們運(yùn)行時可被中
30、斷 【中斷為什么要分為上半部和下半部?】(1) 中斷服務(wù)程序異步執(zhí)行,可能會中斷其他的重要代碼,包括其他中斷服務(wù)程序。因此,為了避免被中斷的代碼延遲太長的時間,中斷服務(wù)程序需要盡快運(yùn)行.(2) 希望限制中斷服務(wù)程序所做的工作,因此處理中斷的時間越短越好。(3) 中斷服務(wù)程序只作必須的工作,其他的工作推遲到以后處理。 【中斷上下文和進(jìn)程上下文的區(qū)別】(1) 中斷或異常處理程序執(zhí)行的代碼不是一個進(jìn)程(2) 它是一個內(nèi)核控制路徑,代表了中斷發(fā)生時正在運(yùn)行的進(jìn)程執(zhí)行(3) 作為一個進(jìn)程的內(nèi)核控制路徑,中斷處理程序比一個進(jìn)程要“輕”(中斷上下文只包含了很有限的幾個寄存器,建立和終止這個上下文所需要的時間
31、很少)簡單地說:l 在進(jìn)程上下文中可以通過current宏關(guān)聯(lián)到當(dāng)前線程,可以睡眠,也可以調(diào)度程序;l 在中斷上下文與進(jìn)程無關(guān),不可睡眠,因此不能從中斷上下文中調(diào)用某些函數(shù)?!拒浿袛?tasklet /工作隊(duì)列優(yōu)缺點(diǎn)及使用場合】軟中斷:優(yōu)點(diǎn):可以并發(fā)運(yùn)行在多個CPU上(及時同一類型的也可以),具有可擴(kuò)展性;缺點(diǎn):必須使用可重入函數(shù),對鎖要求高,實(shí)際復(fù)雜度高,靜態(tài)分配不靈活;適用場合:對時間要求嚴(yán)格、執(zhí)行頻率很高和連續(xù)性要求很高的情況;Tasklet:優(yōu)點(diǎn):接口更簡單,鎖保護(hù)要求低,而且兩個不同類型的tasklet不能同時執(zhí)行,所以實(shí)現(xiàn)簡單,動態(tài)可變靈活性好,是有效的軟終端;缺點(diǎn):只能運(yùn)行在一個
32、CPU上,不能并發(fā);使用場合:在不要求擴(kuò)展到多CPU的話,盡可能選擇tasklet而不是軟中斷。不能很好線程化的代碼,tasklet意義更大;工作隊(duì)列:優(yōu)點(diǎn):缺點(diǎn):造成的開銷最大,因?yàn)橐獱砍兜絻?nèi)核線程甚至是上下文切換;使用場合:如果中斷的延期工作需要運(yùn)行于進(jìn)程上下文,工作隊(duì)列是唯一的選擇?!拒浿袛唷縧 kernel/softirq.c定義了一個32個元素的結(jié)構(gòu)數(shù)組l 固定 登記的softirqs最大數(shù)目不能動態(tài)改變.l 工作時允許中斷.一個softirq不能搶占另一個。只能被中斷服務(wù)程序搶占.l 另一個softirq,甚至是同一個可運(yùn)行于另一個CPU.l 軟中斷都要在do_softirq()中
33、執(zhí)行l(wèi) 引入軟中斷主要為了可擴(kuò)展性【軟中斷的使用】l 注冊處理程序 open_softirq(索引號,處理程序,NULL)l 觸發(fā)軟中斷 raise_softirq(索引號)l 返回指定CPU上未處理的軟中斷softirq_pending(CPU)【軟中斷的執(zhí)行】l 中斷處理程序在返回前觸發(fā)它的軟中斷,使其稍后執(zhí)行l(wèi) 檢查和執(zhí)行待處理的軟中斷的時機(jī):- 中斷處理結(jié)束時- 內(nèi)核線程ksoftirqd在系統(tǒng)空閑時(每一個處理器有一個這樣的線程)- 內(nèi)核代碼中其他調(diào)用do_softirq函數(shù)時l 使用軟中斷的情況:對時間要求最嚴(yán)格和最重要的下半部使用- 網(wǎng)絡(luò)和SCSI設(shè)備- 內(nèi)核定時器和taskle
34、t【Tasklets】l Tasklets 實(shí)現(xiàn)于softirq之上,實(shí)際上也是softirqs.l 同一Tasklet 同時只運(yùn)行于一個 CPU.不同類tasklet可在不同CPU上同時執(zhí)行l(wèi) 同一處理器上不會有tasklet互相搶占【解釋tasklet 思想】中斷的下半部可以通過多種機(jī)制實(shí)現(xiàn),其中tasklet是常用的一種形式,而tasklet的實(shí)現(xiàn)基礎(chǔ)是軟中斷。軟中斷作為下半部機(jī)制的代表隨著SMP應(yīng)運(yùn)而生,它使得對時間不敏感的任務(wù)延后執(zhí)行,而且可以在多個CPU上并行執(zhí)行。Tasklet是在兩種軟中斷類型的基礎(chǔ)上實(shí)現(xiàn)的(HI_SOFTIRQ和TASKLET_SORFTIRQ),但是由于其特
35、殊的實(shí)現(xiàn)機(jī)制,降低了設(shè)備驅(qū)動程序開發(fā)者的負(fù)擔(dān),因此如果不需軟中斷的并行性,tasklet就是最好的選擇?!総asklet_schedule()調(diào)度過程】(1) 檢查tasklet的狀態(tài)是否為TASKLET_STATE_SCHED,如果是,則立即返回;(2) 保存中斷狀態(tài),禁止本地中斷;(3) 把需要調(diào)度的tasklet指定處理器的tasklet_vec或tasklet_hi_vec鏈表;(4) 喚起TASKLET_SOFTIRQ或HI_SORTIRQ軟中斷,這樣在下一次調(diào)用do_softirq()時會執(zhí)行該tasklet;(5) 恢復(fù)中斷到原狀態(tài)并返回【tasklet處理過程】(1) 禁止中斷
36、,取當(dāng)前CPU tasklet_vec或tasklet_hi_vec鏈表(2) 將當(dāng)前處理器的這兩個鏈表清空;(3) 允許響應(yīng)中斷;(4) 循環(huán)遍歷鏈表上的每一個待處理的tasklet;(5) 若是多處理器系統(tǒng),則檢查TASKLET_STATE_RUN判斷這個tasklet是否在其他處理器上運(yùn)行,如果在運(yùn)行,則跳轉(zhuǎn)掉下一個tasklet,否則置其狀態(tài)為TASKLET_STATE_RUN;(6) 檢查tasklet是否被禁止(count=0),若是 跳到下個tasklet;(7) 執(zhí)行tasklet程序;(8) 執(zhí)行完畢后,清除TASKLET_STATE_RUN標(biāo)志;(9) 重復(fù)下一個taskl
37、et;直到所有的tasklet處理完【tasklet的使用】l 編寫tasklet處理函數(shù)void my_tasklet_fun (unsigned long data)l 聲明tasklet靜態(tài) DECLARE_TASKLET(my_tasklet,my_tasklet_func,data); 動態(tài)tasklet_init(t,tasklet_handler,dev)l 調(diào)度 tasklettasklet_schedule(&my_tasklet)l 登記my_tasklet, 然后允許系統(tǒng)在合適的時間調(diào)度它。l 其state成員,取值為TASKLET_STATE_SHCED時表明其已被調(diào)度
38、,準(zhǔn)備運(yùn)行。TASKLET_STATE_RUN表示正在運(yùn)行【工作隊(duì)列】工作隊(duì)列使用內(nèi)核線程來執(zhí)行驅(qū)動中需延遲執(zhí)行的工作(Bottom Half), 這些內(nèi)核線程被稱為工作線程l 在Linux2.6 內(nèi)核中, 系統(tǒng)除了提供默工作認(rèn)線程來幫助驅(qū)動方便的執(zhí)行延遲操作,還允許驅(qū)動自己產(chǎn)生自定義的工作線程來執(zhí)行某些特殊的延遲工作。l 默認(rèn)工作線程被稱作events/n, 其中n 為CPU 個數(shù), 也就是說, 每個CPU 都有一個默認(rèn)工作線程。l 一般大多數(shù)驅(qū)動都使用默認(rèn)工作線程來執(zhí)行自己的下半部工作。l 某些情況下, 驅(qū)動產(chǎn)生自己的自定義工作線程可以滿足更高的性能要求, 并可以減輕默認(rèn)工作線程的負(fù)擔(dān)?!?/p>
39、worker_thread()線程函數(shù)】所有的工作線程都是普通內(nèi)核線程,使用worker_thread( )作為線程函數(shù)l 該線程函數(shù)在進(jìn)行一段初始化操作后便進(jìn)入無限循環(huán), 并睡眠等待。l 當(dāng)有需處理的延遲工作被加入到工作隊(duì)列中時, 該線程函數(shù)被喚醒并循環(huán)處理對應(yīng)工作隊(duì)列中每一個工作單元; l 當(dāng)工作隊(duì)列中沒有工作單元需要被處理時, 它又重新進(jìn)入睡眠狀態(tài), 等待下一次的喚醒。l 主要任務(wù)就是遍歷工作隊(duì)列上所有需要被處理的工作單元, 如果隊(duì)列非空, 則調(diào)用run_workqueue( )處理具體的延遲工作。- 通過list_entry 取得每一個工作單元的work_struct 結(jié)構(gòu), 并以wo
40、rk- data 為參數(shù)調(diào)用其具體處理函數(shù)work- func( )?!竟ぷ麝?duì)列的使用】l 驅(qū)動為需要延遲處理的工作建立一work_struct 結(jié)構(gòu), 該結(jié)構(gòu)即為工作單元, 它還包含一函數(shù)指針用來處理具體的延遲工作; l 該工作單元被添加到當(dāng)前CPU 的默認(rèn)工作線程或自定義工作線程的工作隊(duì)列中等待處理l 在某一時刻, 工作線程被喚醒, 它將循環(huán)處理工作隊(duì)列中的每一個工作單元l 創(chuàng)建WorkStatic DECLARE_WORK(name, void(*function)(viod*), void* data);l 調(diào)度Workschedule_work(&work)schedule_dela
41、yed_work(&work, delay)l 刷新Workvoid flush_scheduled_work(void)l 取消 Workint cancel_delayed_work(struct work_struct *work)【下半部的選擇】時間要求嚴(yán)格和使用頻度高:使用Softirq,它提供最少的順序保證,應(yīng)采取一些額外的步驟保證數(shù)據(jù)安全,用于的場合不能很好地線程化:tasklet意義較大,有簡單接口,同類tasklet不能同時運(yùn)行延期的工作需運(yùn)行于進(jìn)程上下文:唯一的選擇是work queueCh 9.【臨界區(qū)】訪問和操作共享數(shù)據(jù)的代碼段,整個臨界區(qū)是一個不可分割的指令。多個線程
42、同時訪問共享的資源會存在不安全性【競爭條件】多個線程或者進(jìn)程在讀寫一個共享數(shù)據(jù)時依賴于它們執(zhí)行的相對時間,這種情形叫競爭。這樣的多個線程或者進(jìn)程可能處于同一個臨界區(qū)之中,競爭條件就發(fā)生在這多個進(jìn)程或者線程在讀寫數(shù)據(jù)時,其最終的結(jié)果依賴于多個進(jìn)程的指令執(zhí)行順序?!就健勘苊獠话踩牟l(fā)和防止競爭條件被稱為同步?!舅梨i】有一個或多個執(zhí)行線程和一個或多個資源,每個線程都在等待其中的一個資源,但所有的資源都已經(jīng)被占用了,所有線程都在相互等待,但它們永遠(yuǎn)不放棄已經(jīng)占有的資源,于是任何線程都無法繼續(xù),這便發(fā)生了死鎖?!驹斐刹l(fā)執(zhí)行的原因】(1) 中斷中斷集合可以在任何時刻異步發(fā)生,也就是可能隨時打斷當(dāng)前正
43、在執(zhí)行的代碼;(2) 軟中斷和tasklet內(nèi)核能在任何時刻喚醒或調(diào)度軟中斷和tasklet,打斷當(dāng)前任務(wù);(3) 內(nèi)核搶占因?yàn)閮?nèi)核具有搶占性,所以內(nèi)核中的任務(wù)可能會被另一任務(wù)搶占;(4) 睡眠及用戶空間的同步在內(nèi)核執(zhí)行的進(jìn)程可能會睡眠,這就會喚醒調(diào)度程序,從而導(dǎo)致調(diào)度一個新的用戶進(jìn)程執(zhí)行;(5) 對稱多處理兩個或多個處理器可以同時執(zhí)行代碼?!痉乐顾梨i死鎖的方法】(1) 鎖的順序至關(guān)重要(2) 防止饑餓(3) 不要對同一個鎖上兩次鎖(4) 鎖的方案過于復(fù)雜易導(dǎo)致死鎖【爭用】確切應(yīng)該是鎖的爭用,是指當(dāng)鎖正在被占用時,有其他線程試圖獲得該鎖?!究蓴U(kuò)充性】系統(tǒng)可被擴(kuò)展的程度,考慮大量的進(jìn)程,處理器以
44、及內(nèi)存?!景踩a】在中斷處理程序(或?qū)ΨQ多處理器、內(nèi)核強(qiáng)占)中能避免并發(fā)訪問的安全代碼稱作中斷(SMP、強(qiáng)占)安全代碼。Ch 10.【原子操作與非原子操作】原子操作形如:test_bit()非原子操作:_test_bit(),執(zhí)行比原子操作快【屏障】所有可能重新排序和寫的處理器提供了機(jī)器指令來確保順序要求,同樣也可以指編譯器不要給定點(diǎn)周圍的指令序列進(jìn)行重新排序,這些確保順序的指令叫屏障。wmb()、rmb()、mb()分別為寫屏障、讀屏障、讀寫屏障?!拘盘柫俊縧 down_interruptible()試圖獲得信號量,若不可用則把進(jìn)程設(shè)為TASK_INTERRUPTIBLE狀態(tài)并進(jìn)入睡眠l
45、down_trylock()通過堵塞方式試圖獲取信號量【自旋鎖】Linux內(nèi)核最常見的鎖。一個執(zhí)行線程要想訪問被自旋鎖保護(hù)的共享資源,必須先得到鎖,而自旋鎖最多只能被一個可執(zhí)行的線程持有。鎖持有者在訪問完共享資源后必須釋放鎖。而如果一個執(zhí)行線程在獲取自旋鎖時,沒有任何執(zhí)行線程保持鎖,則立即得到鎖;若獲取自旋鎖時已經(jīng)被持有,那么該線程就會一直進(jìn)行“忙循環(huán)”“旋轉(zhuǎn)”“等待鎖重新可用”的自旋鎖,直到所要自旋鎖的保持者釋放鎖,請求鎖的執(zhí)行線程便能立即得到它。 持有自旋鎖不允許睡眠【自旋鎖】l 任何時候只能有一個線程持有的鎖l 自旋鎖被一個線程持有時,其他線程不能獲得這個鎖,只能忙等這個鎖, l 長時間
46、占有自旋鎖并不是一個明智的方法l 警告:自旋鎖不可遞歸- 如果已經(jīng)獲得自旋鎖,然后再次試圖獲得將會導(dǎo)致死鎖l 用于中斷處理程序時要注意:- 首先需要禁止本地中斷,否則可能會試圖兩次獲得自旋鎖- 有一個很方便的接口禁止本地中斷的同時獲得自旋鎖: spin_lock_irqsave() 保存當(dāng)前中斷狀態(tài),禁止本地中斷,獲得鎖?!净コ怏wmutex的受限性】l 任何時刻中只有一個任務(wù)可以持有mutex,也就是說,mutex的使用計(jì)數(shù)永遠(yuǎn)是1l 給mutex上鎖者必須負(fù)責(zé)給其再解鎖-你不能在一個上下中鎖定一個mutex,而在另一個上下文中給它解鎖。這個限制使得mutex不適合內(nèi)存同用戶空間復(fù)雜的同步背景
47、。最常使用的方式是:在同一上下中上鎖和解鎖l 遞歸地上鎖和解鎖是不允許的。也就是說,你不能遞歸地持有同一個鎖,同樣你也不能再去解鎖一個已經(jīng)被解開的mutex。l 當(dāng)持有一個mutex時,進(jìn)程不可以退出l Mutex不能再中斷或者下半部使用,即使使用mutex_trylock()也不行l(wèi) Mutex只能通過官方API管理:它只能使用官方API初始化,不可以被拷貝、手動初始化或者重復(fù)初始化?!拘盘柫颗c自旋鎖的區(qū)別】當(dāng)一個進(jìn)程試圖獲取一個被占用的自旋鎖時,它必須不斷的查看鎖是否被釋放,而對信號量來說,進(jìn)程不必一直忙等,而是把自己登記到一個等待隊(duì)列中,然后自己睡覺去了。信號量:適用于鎖會被長時間持有的
48、情況,任務(wù)可睡眠自旋鎖:適用于被短時間占有的鎖,可用于中斷上下文l 除非受到muex約束,否的相比信號量,優(yōu)先使用mutex【完成變量】類似于信號量 l 一個任務(wù)在等待完成變量,另一個進(jìn)程在進(jìn)行某種工作l 另一個進(jìn)程完成工作后,使用完成變量喚醒等待的進(jìn)程【BKL: 大內(nèi)核鎖】大內(nèi)核鎖(BKL)是全局自旋鎖,其特性:- 可以持有BKL睡眠- 可遞歸- 可在進(jìn)程上下文中使用BKL- 有害l BKL多用于保護(hù)代碼而不是數(shù)據(jù)【順序鎖】用計(jì)數(shù)變量上鎖,適用場合:l 數(shù)據(jù)存在很多讀者l 數(shù)據(jù)寫者很少l 雖寫者很少,但希望寫優(yōu)先于讀,而且不允許讀者饑餓l 數(shù)據(jù)很簡單【同步的方法】原子操作:是指不會被線程調(diào)度
49、機(jī)制打斷的操作,這種操作一點(diǎn)開始,就一直運(yùn)行到結(jié)束,中間不會切換到另一個線程;自旋鎖:為了實(shí)現(xiàn)保護(hù)共享資源,防止多處理器并發(fā)而提出的一種鎖機(jī)制。一個執(zhí)行單位要想訪問被自旋鎖保護(hù)的共享資源必須先得到鎖,否則將自旋等待獲取鎖;信號量:是一種睡眠鎖,沒有獲得信號量的任務(wù)則進(jìn)入等待隊(duì)列睡眠,直到信號量被釋放后才被喚醒,獲得信號量去執(zhí)行;是在多線程環(huán)境下用來保證兩個或多個關(guān)鍵代碼段不被并發(fā)調(diào)用的一種設(shè)施。在進(jìn)入一個關(guān)鍵代碼段錢線程必須獲取一個信號量,執(zhí)行完成后釋放信號量;完成變量:若在內(nèi)核中一個任務(wù)需要發(fā)出信號通知另一個任務(wù)發(fā)生了某個特定事件,則使用完成變量,完成變量喚醒在完成變量上等待的任務(wù);BKL(
50、大內(nèi)核鎖):大內(nèi)核鎖基于小等待自旋鎖,是一個全局自旋鎖,可以使一個進(jìn)程多次請求鎖(遞歸鎖),保證一個進(jìn)程只能取得一次鎖,在釋放前任何鎖定動作都不會導(dǎo)致實(shí)質(zhì)上再次鎖定,這樣避免本進(jìn)程多次鎖定而導(dǎo)致死鎖。(還有seq鎖、原子操作、互斥體)【為什么需要多種鎖機(jī)制】使用鎖的上下文環(huán)境不同,加鎖的時間長短不同,維護(hù)鎖的開銷不同,所以要設(shè)計(jì)幾種鎖來適應(yīng)不同使用情況。 原子操作保證指令執(zhí)行過程不被打斷,只能避免對原子類型的數(shù)據(jù)的并發(fā)訪問,而無法對避免對一整塊數(shù)據(jù)的并發(fā)訪問;自旋鎖快速簡單,加鎖時間不長且代碼不會休眠,但會一直忙循環(huán)旋轉(zhuǎn),占用CPU的時間,同時禁止內(nèi)核搶占,但是正因?yàn)檫@種鎖不會睡眠的特性,使得
51、在中斷處理程序中只能使用這種鎖避免并發(fā),而其他的鎖會因睡眠而禁止使用;信號量適用于加鎖時間長且允許睡眠的情況,它使得進(jìn)程睡眠,以實(shí)現(xiàn)更好的資源的利用,它允許內(nèi)核搶占,但是信號量的開銷很大;BKL鎖允許遞歸使用,不會出現(xiàn)死鎖,但很少被使用且是有害的;seq鎖適用讀寫共享數(shù)據(jù),輕量級,對寫者有利,讀者循環(huán)等待?!窘箵屨肌繂栴}:l 由于內(nèi)核時可搶占的,進(jìn)程可以在任何時候停下來讓另一個優(yōu)先級更高的進(jìn)程運(yùn)行l(wèi) 被搶占的進(jìn)程可能處于臨界區(qū)解決方法:使用自旋鎖作為非搶占區(qū)的標(biāo)記Ch 12.【物理頁】l MMU,內(nèi)存管理單元,把虛擬地址轉(zhuǎn)換為物理地址的硬件,以頁為單位管理內(nèi)存:32位:4K、64位:8Kl
52、每一個物理頁有一個struct page(page結(jié)構(gòu)與物理頁相關(guān),而并非與虛擬頁相關(guān)):flags: 臟,加鎖等.count: 使用計(jì)數(shù),通過page_count()訪問virtual: 虛地址【區(qū)】Linux分為6個區(qū),主要用到4個區(qū):ZONE_DMA:包含的頁能用來執(zhí)行DMA操作ZONE_DNA32:只能被32位設(shè)備訪問ZONE_NORMAL:能正常映射的頁ZONE_HIGHEM:包含“高端內(nèi)存”,其中的頁不能永久地映射到內(nèi)核地址空間【頁分配】l page指針轉(zhuǎn)換為邏輯地址:page_address(struct page *page)l 分配連續(xù)物理頁,返回page指針:struct
53、page *alloc_pages(mask, order)l 分配連續(xù)物理頁,返回邏輯地址:_get_free_pages(mask,order)l 分配單個物理頁,返回page指針:alloc_page(mask)l 分配單個物理頁,返回邏輯地址:_get_free_page(mask)l 分配單個全零物理頁,返回邏輯地址:get_zeroed_page(mask)【頁釋放】l void _free_pages(struct page *page, unsigned int order)l void freepages(unsigned long addr, unsigned int or
54、der)l void free_page(unsigned int order)【字節(jié)分配】l void *kmalloc(size_t size, int flags)返回指向分配的內(nèi)存的指針,物理頁連續(xù)l vmalloc()分配的內(nèi)存虛擬地址是連續(xù)的,物理地址無須連續(xù)【gfp_mask標(biāo)志】分為三類:(1) 行為修飾符:內(nèi)核應(yīng)當(dāng)如何分配所需的內(nèi)存。(2) 區(qū)修飾符:從哪個區(qū)分配內(nèi)存(3) 類型標(biāo)志:前2者的組合注:不能給_get_free_pages()或kalloc()指定ZONE_HIGHMEN,因?yàn)檫@兩個函數(shù)返回的都是邏輯地址,而不是page結(jié)構(gòu),這兩個函數(shù)分配的內(nèi)存當(dāng)前有可能還沒有
55、映射到內(nèi)核的虛擬地址空間,因此也可能根本沒有邏輯地址。【Slab分配器】一種策略,用于緩存內(nèi)核對象:Object: 經(jīng)常使用的數(shù)據(jù)結(jié)構(gòu),例如inodeCache: 存儲某種類型的對象.Slab: 包含有緩存的對象.每種對象類型有一個cache.Cache包含一個或多個slab.Slab可能會占有一個或多個連續(xù)的內(nèi)存頁有三種狀態(tài):(1) Full 沒有自由的對象.(2) Partial 部分自由. 從這里分配.(3) Empty含有未分配的對象【Slab 算法】(1) 為特定的對象類型選擇合適的cache.減少了內(nèi)部碎片.(2) 從cache中的第一個部分滿的slab分配對象.減少了頁的分配和釋放.(3) 如果沒有部分滿的slab, 從空的slab分配.(4) 如果沒有空的slab,給cache分配新的slab.【如何選擇內(nèi)存分配函數(shù)】(a
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度電子產(chǎn)品oem質(zhì)量檢測合同范本共
- 2025至2030年中國橫編織機(jī)行業(yè)投資前景及策略咨詢研究報告
- 2024年中國氣體助焊劑市場調(diào)查研究報告
- 承包合同范文集錦8篇
- 2025版二手房交易全程保障甲乙中介服務(wù)協(xié)議
- 2024年中國三位八通換向閥市場調(diào)查研究報告
- 汽車銷售年終總結(jié)模板10篇
- 2025版門窗安裝與玻璃深加工一體化承包合同3篇
- 2025至2030年中國綠色擋板行業(yè)投資前景及策略咨詢研究報告
- 修船合同范本
- 2025屆高考語文復(fù)習(xí):散文閱讀 課件
- 國家開放大學(xué)電大《文獻(xiàn)檢索(本科)》2024-2024期末試題及答案
- 國家環(huán)保部《自然保護(hù)區(qū)綜合科學(xué)考察規(guī)程》(環(huán)涵2022139號)
- 新開科室籌備工作計(jì)劃
- 河北省會計(jì)師事務(wù)所收費(fèi)標(biāo)準(zhǔn)
- 兒科護(hù)理學(xué)智慧樹知到期末考試答案章節(jié)答案2024年右江民族醫(yī)學(xué)院
- 供應(yīng)鏈組織管理智慧樹知到期末考試答案章節(jié)答案2024年山東大學(xué)
- 家庭教育組織架構(gòu)設(shè)計(jì)(3篇模板)
- JT-T-999-2015城市公共汽電車應(yīng)急處置基本操作規(guī)程
- 2021年安全工程師《建筑施工安全》真題及答案解析
- 2024年新“國九條”及配套政策要點(diǎn)解讀分析報告
評論
0/150
提交評論