存在內存的特定地址,啓動執行,檢查計算機硬件java
加載位於硬盤特定地址的BootLoader,管理權交給BootLoadernode
BootLoader加載os,管理權交給os算法
應用程序主動向操做系統發起請求指令(syscall)。同步或異步chrome
應用程序執行中被動觸發操做系統執行指令。應用程序意想不到的行爲。除以零、訪問未知地址等。同步。應用能夠感知shell
外設向操做系統發出請求,須要操做系統提供支持。異步。對應用透明編程
陷阱指的是當異常或者中斷髮生時,處理器捕捉到一個執行線程,而且將控制權轉移到操做系統中某一個固定地址的機制。現代操做系統是由中斷驅動的,中斷分爲硬件中斷和軟件中斷。而陷阱屬於一種軟件中斷。若是計算機沒有進程要執行,沒有用戶響應請求,操做系統將等待某個事件的發生。而事件老是由中斷或者陷阱引發的windows
操做系統爲保證系統正常運行,會提供兩種操做模式:api
兩種模式不會互相干擾。操做系統須要硬件支持來提供雙重模式操做:當用戶進程進行非法操做(非法指令或非法地址訪問)的時候,硬件會向操做系統發出陷阱信號,致使控制權轉移到操做系統,操做系統結束用戶進程並給出錯誤信息數組
運行中的程序。分爲用戶進程和系統進程瀏覽器
內存是cpu和io設備能夠共同訪問的數據倉庫。若是cpu須要訪問磁盤數據,首先生成io調用將數據加載進內存,以後才能直接訪問
編譯器會應用程序生成的地址
實際內存條(主存)和硬盤提供的可用地址
操做系統在其中扮演者預先創建虛擬地址到物理地址映射關係的角色,而且還限制了每一個應用訪問虛擬地址的空間。若是cpu執行某個應用程序時,訪問了不屬於它的空間,就會產生一個內存訪問異常,操做系統會接管並執行相應的異常處理代碼
內存中空閒的,未被使用的空間
分配單元之間,沒被使用的空閒空間
已分配給該應用,可是該應用未利用到的空閒空間
合理的內存管理就是減小這些內存碎片
兩種硬件方案:分段、分頁
將應用分紅多個段:堆、運行棧、程序數據、程序text段。在虛擬地址是連續的,可是映射到物理地址是分離的
分段尋址機制:在分段機制中,要將虛擬地址映射到物理地址,虛擬地址被劃分紅兩個部分,第一段爲segment number,第二段爲segment offset。cpu根據segment number去segment table中定位到該number對應物理內存的base地址,及該segment長度limit。而後經過檢查offset是否小於等於limit,若是不是就觸發異常,若是是該虛擬地址就成功映射到物理地址base+offset
segment table是由操做系統預先創建,並存入硬件
分段在cpu中使用較少,分頁使用較多
分頁相似分段,也是將內存分紅多個部分
在虛擬內存中,這些部分稱爲page(頁),在物理內存中,這些部分稱爲frame(幀)。虛擬地址由page number和page offset定位,物理地址由frame number和frame offset定位,page number與frame number大小能夠不一致,可是二者的offset必須一致,而且page size和frame size大小一致。
硬件尋址的時候根據虛擬地址劃分出page number和page offset,並經過page table和該table的base地址查詢page number到frame number的映射關係,最後定位到frame number,因爲page offset與frame offset一致,因此最終物理地址就是frame number + page offset
分段與分頁惟一不一樣的地方在於每一個segment的大小不一樣,而每一個page大小相同(1k、4k等)。因此segment table須要記錄[segment number -> 物理內存base地址,segment長度limit]映射關係。而page table只須要記錄[page number -> frame number]映射關係
經過分段或分頁中,虛擬內存是連續的,可是定位到物理內存能夠是非連續的,這樣提升了內存利用率,減小了碎片
page table由操做系統創建
假設page size爲1k(2^10),64位操做系統須要創建的page table大小達到2^(64-10)=2^54,這麼大的page table cpu和內存都沒法存放,這致使空間開銷大。即便內存能夠存下,每次尋址都要先查page table再查物理內存,涉及到兩次內存查詢,這致使時間開銷大
每次cpu的MMU(內存管理單元)尋址的時候都會查詢page table,這樣致使時間開銷很大。TLB是MMU中包含的一個緩存,緩存了page table的數據,空間很小速度很快
爲了減小TLB查詢miss,應用須要保證訪問局部性
以二級頁表說明
將虛擬地址分紅三部分:
內存中創建兩個page table,一級page table中存儲二級page table的base地址,二級page table存儲frame number
尋址方式:
這種方式之因此能減小空間,能夠經過64位系統、1k page size狀況來講明:
只用一個page table會致使須要創建大小爲2^54的page table,根據這個page table中的信息判斷虛擬地址是否有對應的物理地址
採用二級page table會讓一級page table成爲二級page table的索引,若是索引不到二級page table無需創建,索引到才須要創建。當虛擬地址遠遠大於物理地址的時候,會極大減小二級page table的item
結合上述結果,可得若是更多級page table會大大減小所需空間,不過也會帶來另一個問題:屢次訪問內存page table導致時間開銷大。這個能夠經過TLB解決
須要爲每一個進程分配多級頁表,以保證進程隔離,進程不會越界訪問其餘進程的虛擬地址。隔離以後,每一個進程看到的虛擬地址可能一致,但映射的物理地址不會相同,這一層經過操做系統保證
多級頁表會致使管理頁表更麻煩,而且大小受虛擬地址影響,並且多級頁表的狀況下須要爲每一個進程分配頁表,因此空間開銷依然不小
反向頁表不一樣,它根據物理地址索引虛擬地址,大小受物理地址限制,而且全部進程共享同一張頁表,因此空間開銷很小。須要區分每一個物理內存對應的應用,就須要引入pid(進程編號)
因爲cpu只能拿到虛擬地址,利用反向頁表的時候,須要遍歷頁表,匹配指定pid和虛擬地址,最終肯定物理地址。至關於遍歷數組的值,肯定索引,時間開銷較大
優化方案
基於hash函數方案:能夠經過傳遞pid和虛擬地址,執行一段hash函數,定位到索引,即物理地址。缺點是設計高效少碰撞的hash算法難度較大,而且訪問hash表會致使多出一次內存訪問,這個能夠經過TLB緩解
內存不夠的狀況下的解決方案之一。將應用使用的內存分紅多個頁管理,當內存不夠用的時候,將應用沒有使用到的頁交換到磁盤,當內存足夠的時候,將應用須要的頁交換到內存。經過操做系統內核和MMU完成
內存置換的時候,須要一些信息,這些信息存在頁表項中
頁表由頁表項組成,每一個頁表項包含
虛存技術將內存置換交給了操做系統,但一樣提出了對應用程序的要求。它但願程序可以保證局部性
當程序達到時間局部性和空間局部性,就說程序的局部性很好,它能讓內存置換次數更少,使得訪問虛存就像訪問內存同樣簡單、快速
當訪問虛擬內存沒法映射到物理內存時,會產生缺頁中斷,流程爲:
局部頁面置換算法
當出現缺頁中斷而且沒有足夠的物理頁面時,須要置換算法保證將一部分頁面寫到磁盤,並騰出相應的空間。
最優置換算法但願保證將要置換的頁面在後面很長一段時間都不會訪問到
不過這種狀況較理想,由於沒法預測將來應用會訪問到的頁面,因此這種方式沒法實現。不過這種算法能夠做爲一個理想評價標準
局部頁面置換算法
操做系統維護一個鏈表,維護使用過的頁信息。鏈表採用先進先出原則,在缺頁中斷髮生時,鏈表表頭的頁會被淘汰。效果較差
局部頁面置換算法
最久未被使用的頁優先被淘汰
採用棧或鏈表實現:每次訪問頁面,若是以前訪問過,則替換到表頭或棧頂,並淘汰表尾或棧底的元素。每次訪問頁面都要遍歷一次鏈表或者棧,時間開銷較大。若是採用hash表,空間開銷大
局部頁面置換算法
將頁組織成一個環形鏈表,當出現缺頁中斷時,指針沿着環形鏈表不斷向後轉動,若是發現訪問位爲1的則將它置爲0,若是碰到訪問位爲0的則淘汰該頁
訪問位是在cpu訪問該頁以後置爲1的,表明該頁最近被訪問過。這個算法至關於給了兩次機會,當須要置換時,會檢查該頁,若是爲1,則置爲0,表示只有最後一次機會留在內存。若是一個頁常常被訪問,操做系統置換檢查時,該位應該老是1
局部頁面置換算法
上述CLOCK算法沒有考慮須要置換的頁面是否被修改過。
加強CLOCK算法思想是優先淘汰沒有訪問而且沒有寫的頁。它引入修改位,將訪問位與修改位視爲二元組,在環形鏈表中:
局部頁面置換算法
淘汰使用最少的頁
這種置換算法有兩個問題:
第二個問題的解決方案是,定時將計數寄存器右移,保證一直未被使用的數據,最後會指數級衰減
給每一個應用分配的物理頁面越多,缺頁率反而越高的異常現象
一個進程當前正使用的邏輯頁面集合。由二元組W(t,△)
|W(t,△)|能夠量化應用局部性,若是頁面數越大,局部性越差
當前時刻,進程實際駐留在內存中的頁面集合,大小等於操做系統分配給該進程的物理頁數,內容取決於操做系統採用的頁面置換算法。
工做集與常駐集:進程不斷訪問內存頁,造成工做集集合,訪問頁的時候會查詢常駐集中頁,若是不存在則引起缺頁中斷
以前介紹的FIFO,LRU,CLOCk,加強CLOCK都是局部頁面置換算法,只考慮某個進程內頁面置換的狀況。全局頁面置換算法會考慮全部進程進行頁置換的狀況。
爲何須要全局置換算法?
每一個進程工做集不斷變化,程序局部性也在不斷變化,操做系統能夠根據這些信息動態調整常駐集大小,避免浪費或者資源不夠。因此,全局頁面置換算法相比局部頁面置換算法,更加合理
爲何介紹局部置換算法?
既然全局置換算法更合理,爲何介紹局部置換算法呢?由於有的局部算法如FIFO,LRU,也能夠用在全局;有的系統更加依賴局部置換算法來保證部分程序出現抖動不會影響全局系統
全局頁面置換算法
常駐集只保存工做集中的頁面,全部不在工做集中的頁面都要置換出去。每次應用訪問內存頁的時候,都會進行置換算法
全局頁面置換算法
思想是根據缺頁率動態調整常駐集大小。當缺頁率太高時,增大常駐集(物理頁幀數);當缺頁率太小時,減少常駐集。保證缺頁率在一個合適的範圍內
實現:
相比較工做集頁置換算法,缺頁率置換算法以缺頁率爲參考依據,工做集置換算法須要在每一個時刻執行算法,缺頁率算法只是在缺頁的時候纔會執行算法
當進程數愈來愈多,分配給每一個進程的物理頁數愈來愈少,致使常駐集永遠沒法包含工做集,導致大量缺頁中斷,操做系統頻繁進行內存置換,cpu利用率大大下降。這種現象稱爲抖動
抖動出現表明操做系統的負載太高,這種負載每每是過多的進程數或不合理的物理頁數致使的。爲了緩解這種狀況,操做系統須要保證:
實際狀況,第一個方案較難實現,每每採起第二個方案
關聯:
區別:
進程包含以下信息:
操做系統用來表明每一個進程的數據結構,簡稱PCB。PCB能夠描述進程的基本狀況和狀態變化的過程,是每一個進程的惟一標識
包含三類信息:
通用操做系統會採用鏈表而不是數組來組織PCB,由於進程會不斷建立和銷燬,因此須要不斷添加和刪除操做,採用鏈表開銷更小
進程生命週期能夠分爲:
其中須要說明的是Running與Ready之間的狀態轉換:內存中有多個就緒的進程須要執行,當進程A執行時間片用完以後,操做系統會切換到進程B,讓進程A進入就緒狀態,進程B進入運行狀態
進程掛起就是當內存不夠用的時候,將進程換出到磁盤。掛起分爲兩種狀態:
掛起涉及到的狀態轉換:
進程激活就是將進程從磁盤換入到內存,涉及到的狀態轉換:
操做系統根據進程狀態,來分開管理進程:
操做系統根據進程的狀態,決定將它插入哪一個隊列中。當進程狀態變化時,操做系統會從原隊列取出,插入新隊列
輕量級進程,是進程中的一條執行流程。一個進程中的不一樣線程,共享相同的數據區、代碼區和打開的系統資源,可是每一個線程有本身獨立的PC、棧、通用寄存器,以便維護各自的執行狀態。進程是資源分配的單位,線程是cpu調度的單位
操做系統採用數據結構TCB來表示線程,線程與進程同樣,也擁有就緒、阻塞、運行三種狀態,以及狀態之間的轉換關係
優勢:
缺點:
例子:
線程所需的資源:
由庫函數實現的線程是用戶線程。採用庫來支持線程的建立、銷燬、調度,操做系統並不知道用戶線程的存在
優勢:
缺點:
由內核維護PCB和TCB
優勢:
缺點:
案例:
內核支持的用戶線程,結合了用戶線程管理開銷小和內核線程穩定性高的優勢。
案例:
用戶線程與內核線程映射關係:
進程切換涉及的幾個關鍵操做:
其中上下文主要指進程使用的寄存器,如PC寄存器、棧寄存器、通用寄存器。這些信息在切換以前必須保存,以便以後恢復執行
操做系統爲存儲這些進程,提供了多種隊列:
int pid = fork();//建立一個進程,並返回子進程id if(pid == 0){ //子進程返回值爲0 exec("program",argc,argv0,argv1,...) }else if(pid > 0){ //父進程返回值爲子進程id ... }else{ //錯誤 ... wait(pid);//等待子進程結束 }
在fork複製進程的時候,會複製全部進程信息,只有其中各自子進程id不一樣,使得fork返回值不一樣
Unix/Linux採用exec加載進程,絕大部分狀況下fork後會使用exec,保證拷貝的子進程可以加載新程序。如上一節代碼,exec會將當前進程全部信息替換爲program進程信息
wait()用於父進程等待子進程結束
不一樣次序會有不一樣結果:
exit()用戶進程資源回收
其中exec的時候可能出現兩種狀況:
從就緒進程中挑選一個佔用cpu的過程,若是有多cpu,還須要提早選出一個可用的cpu
進程調度涉及到上下文切換
進程調度時機,首先須要知足這兩個條件其中一個才能產生調度:
其次,還須要分狀況討論具體調度時機:
非搶佔系統:
可搶佔系統:
長進程:執行時間較長的進程
短進程:執行時間較短的進程
進程調度算法之一。優先服務先入隊列的進程
優勢:
缺點:
進程調度算法之一。優先服務短進程。涉及到兩個技術點:
優勢:
缺點:
進程調度算法之一。根據就緒隊列中進程列出以下公式:
R=(w+s)/s
等待時間越長,R越大;執行時間時間越長,R越小。該算法優先服務R最大的進程。可見,它至關於短進程優先算法的改進版
優勢:
缺點:
調度算法之一。指定時間片大小爲N,按前後順序取出就緒隊列中的進程執行,時長不超過N,執行完成以後,取下一個進程繼續執行。取進程的順序與先來先服務一致,可是每一個進程執行時間不得超過N
優勢:
缺點:
經驗規則:一般設置成10ms,能夠保證上下文切換開銷在1%之內
調度算法之一。將就緒隊列分爲多級子隊列,根據每一個隊列具體狀況的不一樣,採用不一樣的算法,是一種綜合使用全部算法的一種算法
多個子隊列之間採用時間片輪轉算法來調度,每一個隊列保證必定的cpu執行時間。
如:兩個隊列,前臺交互式,佔80%時間,後臺批處理,佔20%時間。則每一個執行週期會執行4次前臺進程和1次後臺進程
多級隊列算法改進版。多級隊列算法沒有考慮到實際隊列中進程執行時間,有的較長但放在了前臺隊列,致使真正響應快速的進程沒有獲得更高的優先級
將多級子隊列按優先級從高到低劃分,優先級越低,分得的時間片越大,適合執行批處理任務,優先級越高,分得的時間片越小,適合執行交互式任務。執行順序從高到底,高優先級隊列執行完了才執行低優先級隊列,在規定時間片內每執行完的進程,被下放到低一級的隊列,但獲取到了更多時間片
優勢:
缺點:
這是實際系統會採用的算法
按用戶組重要程度,給他們使用的系統資源劃分優先級,沒用完的資源用比例劃分
不作詳細介紹
有些系統不只要保證功能性,更要保證明時性,但願能再可預測的時間以內完成某個功能。它對吞吐量要求並不高,可是對實時響應要求很是高。根據實時程度,分爲兩種:
一個實時任務中涉及的重要概念
系統每每由多個實時任務組成,多個實時任務一般是週期性請求,如圖週期爲5
其中假設週期爲5,最大執行時間爲1,則使用率爲1/5
爲保證調度系統實時可控,須要確立衆多任務調度順序,有兩種方法
任務週期越短(速率越快)的優先級越高
由於任務的週期(速率)是調度以前就能肯定好的,因此它是靜態優先級調度算法
請求的任務中,截止時間越早,優先級越高
任務不一樣,截止時間也不一樣,因此只有處理任務請求的時候才能知道截止時間,因此它是動態優先級調度算法
選取其中一個cpu做爲主,進行調度和資源訪問,無需同步,可是沒法利用多處理器
簡稱SMP,每一個cpu運行本身的調度程序,訪問共享資源的時候會須要同步,同步開銷較大,可是更加通用。多處理器調度實際上是考慮如何將進程分配給cpu,有兩種方案:
靜態進程分配:爲每一個cpu維護一個就緒隊列,進程一旦分配到這些隊列,會一直屬於該隊列,進程一旦執行就不會被切換,至關於將進程綁定給cpu
動態進程分配:爲全部cpu維護一個共享就緒隊列,進程會分配給空閒可用的cpu執行,中途會被切換
低優先級進程阻塞高優先級進程的現象
如三個進程A,B,C,優先級A<B<C
這樣B就阻塞了C的執行
優先級反置的解決方案之一
當低優先級佔有資源而且高優先級進程申請資源時,一旦低優先級進程被阻塞(如A被B阻塞),就讓它的優先級繼承高優先級進程(讓A繼承C的優先級),這樣就能解除阻塞順利搶佔cpu並執行
優先級反置的解決方案之一
當進程佔用資源時,將它的優先級提高爲M(M=全部可能佔有該資源進程的最高優先級),保證讓該進程不會被阻塞
缺點:該方案的缺點明顯,它的濫用優先級提升的功能,當全部進程優先級同樣的時候,這種方案也沒用了
優勢:
缺點:
之因此進程併發會出現問題,是由於不少進程操做都不是原子操做,致使執行一半被中斷,並切換到另外一個進程,使得數據正確性和一致性受到影響
原子操做是一組不可中斷的操做,裏面可能涉及多個步驟,要麼所有成功,要麼所有失敗,不可能出現部分紅功部分失敗的狀況
進程之間有三種交互狀況:
進程隔離:各進程資源獨立,併發不會致使問題
共享資源:訪問共享資源,會帶來三個問題
操做系統要知足共享資源的同時又能提升效率,就必須提供一種高效的同步互斥機制
通訊協做:經過互相通訊來傳遞信息
將訪問共享資源的一片代碼稱爲臨界區
進入區 臨界區 退出區 剩餘區
臨界區訪問規則:
經過禁用硬件中斷能夠很好的實現對臨界區訪問的同步,它能夠保證進程不會被中斷,也沒有進程上下文切換,也沒有併發執行。它的思想是經過限制併發、並行,保證進程執行的正確性和一致性
優勢:
缺點:
現代操做系統提供了禁用中斷及恢復中斷的指令,可是不多使用
基於軟件方式的實現兩個線程同步的經典算法
思想是提供兩個共享變量,並組合使用,來表明是否能夠訪問臨界區。能夠很好的協調多個線程訪問,而且符合臨界區訪問規則
優勢:
缺點:
經過編程抽象的一種同步機制,底層依賴於硬件支持,保證一個時間點只能有一個線程訪問共享資源。涉及到一個變量和兩個操做
鎖操做必須保證是原子的。cpu提供了兩個原子性操做,庫函數經過使用這兩個原子操做,來實現鎖語義
cpu提供的原子操做
class Lock{ int value=0; WaitQueue q; void lock(){ while(testAndSet(value)) block(currentThread);//將當前線程放入阻塞隊列,放棄cpu。同時調度其餘線程;若是不作任何操做,就是忙等待 } void unlock(){ value=0; wakeup(otherThread);//將阻塞隊列中的線程喚醒到就緒隊列 } }
優勢:
缺點:
基於鎖方案的同步機制更加經常使用
經過編程抽象的一種同步機制。由一個整數、兩個方法、一個隊列組成
其中信號量提供給用戶用,但P()和V()方法由操做系統來實現,優先級比應用進程的優先級,不會被中斷,保證了兩個方法的原子性
信號量是一種公平的同步方法,先阻塞的線程先進等待隊列,而且優先被喚醒。相較而言,自旋鎖沒法保證公平
用信號量解決生產者消費者問題
在早期操做系統中使用較多,如今不多使用,由於使用複雜,容易出錯。而且信號量中P是操做系統來實現,優先級高,可能會保持阻塞,造成死鎖
不少現代編程語言(java)使用的一種同步模型,是一種高級同步機制
由如下成分組成:
管程解決生產者消費者問題
其中count就是條件變量
其中Wait操做會釋放鎖,避免出現信號量中的死鎖問題,使用相對容易
在T2喚醒T1以後,爲了高效不切換,優先繼續讓T2線程執行(沒法肯定到底哪一個執行),直到T2釋放鎖,T1才恢復執行。java中採用此方案
while(count==n){ wait() }
因此上述代碼中,wait的線程被喚醒後,可能仍是沒法執行,致使count的值可能遭到修改,因而必須使用while循環從新判斷一次
在T2喚醒T1後,T2釋放縮,T1搶佔並執行(肯定T1搶佔)
if(count==n){ wait() }
因此上述代碼,wait的線程被喚醒後,會搶佔執行,期間不會有其餘線程修改count的值,因此無需重複判斷
hoare側重於做爲原理講解管程執行流程,而henson才適合用在真正的系統
五個哲學家,五根筷子,每一個人兩邊都放了筷子,組成環路。哲學家有兩個操做:
可能出現一種狀況,全部哲學家拿起左邊的筷子,等着右邊的筷子,最後都沒法進食,活活餓死。這就是所謂的死鎖狀況
解決方案:
有四種狀況:
根據讀者、寫者的實現機制不一樣,可能採用不一樣的優先策略:
java的讀寫鎖就是利用管程思想實現了讀者-寫者機制
多個進程之間互相等待對方釋放資源,而且永遠沒法結束的一種現象
死鎖出現的必要條件:
資源互斥:至少有一個資源是互斥類型的,不能容許兩個或兩個以上的進程同時訪問
佔有並等待:至少有一個進程佔有資源並等待另外一部分資源才能完成任務
非搶佔:資源是不可搶佔的,必須由佔用進程自願釋放
循環等待:必須存在相似以下現象
只有知足這四個條件,纔會出現死鎖
針對死鎖的處理方法:
提早預防死鎖,死鎖的必要條件有四個,只要其中任何一個不知足,死鎖就不會出現
在進程申請資源的時候動態判斷有沒有出現死鎖的可能,若是有就不容許進程使用資源
算法:當進程請求資源時,系統判斷資源分配後是否處於安全狀態,若是是則分配,不然暫停分配
安全狀態指:
一系列進程P1到Pn,保證Pi申請的資源<=當前可用資源+全部Pj佔有的資源,j<i。若是Pi申請的資源不能當即分配,暫停Pi,等到全部Pj完成
安全狀態與死鎖的關係
是一種基於安全狀態判斷的死鎖算法
核心思想:每一個客戶會申請須要的最大資金量,銀行會根據你已經佔有的資金,力所能及的將剩餘部分借給客戶。客戶在借完資金後會及時歸還,保證銀行有充足的儲備繼續借款
數據結構:
Need=Max-Allocation
算法:
Finished[i]=false,Need[i] < Allocable
的進程,表示i能夠申請資源,不然執行步驟4Work += Allocation[i],Finished[i]=true
,由於i申請的資源最後會被回收,因此忽略分配過程,直接跳到回收環節。執行步驟2基於銀行家算法的思想,判斷會不會出現死鎖。在完成算法後,存在Finished[i]=false,表明進程i會致使死鎖狀態,稱i爲死鎖進程
經過結束進程來恢復死鎖:
顯而後者更好,可是會根據以下條件考慮該優先終止哪一個進程:
經過搶佔進程資源來恢復死鎖:
將死鎖進程回退到安全狀態,並搶佔它的資源,開銷小,可是會出現飢餓現象——進程恢復後又進入死鎖狀態,繼續被搶佔
簡稱IPC,進程間交互信息
能夠分爲阻塞與非阻塞
根據通訊鏈路的緩衝容量可分爲
進程間基於中斷傳遞消息的一種機制。如經過ctrl+c終止運行的程序
原理:應用進程註冊信號處理函數,當出現中斷時,操做系統會根據信號回調信號處理函數。ctrl+c是操做系統默認給每一個進程添加的信號處理函數
缺點是侷限性大,只能傳遞信號類型的消息
進程基於內存文件的通訊方式
在命令ls | more
程序中
這樣就在內存中創建了兩個進程的消息通道
內核提供一個FIFO隊列,提供給不一樣進程通訊
優勢:
缺點:
優勢:
缺點:
實現機制:
基於頁表來實現。不一樣進程有本身的頁表,操做系統將它們的頁表映射到同一個物理地址空間,就完成了進程間共享內存
操做系統中將磁盤數據組織成文件系統,提供對這些持久化數據的操做
功能:
文件系統須要被掛載才能被訪問,它被掛載的目錄稱爲掛載點
根據文件系統的類型分爲:
分佈式文件系統會產生安全性、一致性等問題,比本地磁盤文件系統更復雜
文件系統組織磁盤上數據的方式,並抽象了一些屬性用於簡化這些持久化數據的管理
文件屬性:
將文件分爲兩部分:
目錄是一種特殊的文件,其內容是文件索引表,表的每一項是二元組<文件名,指向文件的指針>。操做目錄就是操做文件索引表
應用程序都是經過系統調用來訪問目錄
讓多個文件名指向同一個文件,看起來就像給文件起了別名
有兩種起別名的方式:
ln src dest
ln -s src dest
可能出現文件子目錄指向父目錄,致使出現循環目錄的狀況,這種狀況會導致目錄遍歷永遠沒法結束
常見的處理方式是設置一個最大遍歷層數
文件系統中的名字解析就是根據文件路徑,讀取文件信息
如/bin/ls
解析過程爲:
進程每讀取文件的時候,都要從根目錄進行名字解析,會致使效率很低。因此操做系統爲每一個進程設置了一個目錄PWD,表明當前工做目錄。這樣當訪問一些當前目錄存在的文件時,不須要再從根目錄開始遍歷
這種機制提供了一種基於相對路徑來訪問文件的方式
簡稱VFS,是對底層各個不一樣文件系統的一個抽象(各個磁盤文件系統和網絡文件系統),對上層提供一個統一的api(open、close、read、write)
全部文件系統實現不一樣,但有些公共數據結構仍是一致的
簡稱superblock,每一個文件系統有一個,記錄了文件系統相關信息:文件系統的類型、數據塊個數與大小、空閒塊個個數與大小等信息
在文件系統掛載時加載到內存
簡稱inode,每一個文件有一個,記錄了文件相關信息:文件大小、數據塊位置、訪問權限、擁有者等
在訪問文件時加載到內存
簡稱dentry,每一個目錄項(文件、目錄)有一個,記錄了目錄相關的信息:文件控制塊的位置、父目錄、子目錄等
與文件控制塊不一樣的是,它側重於對目錄信息的描述,並且VFS利用目錄項控制塊將文件系統組織成樹狀結構
在遍歷目錄時會加載到內存
文件系統組織視圖
文件系統存儲視圖
其中
內存中緩存磁盤數據塊的一部分區域
在讀的時候提供預讀取:預先讀取後面的數據塊
在寫的時候延遲寫:寫到緩存就返回,操做系統定時flush
簡稱page cache。因爲虛擬內存是基於頁來管理內存,文件系統基於塊來管理文件數據,頁和塊大小不一樣,須要一個機制統一二者的管理方式
頁緩存實現中屏蔽了底層數據塊的管理,上層統一提供基於頁的管理方式,供虛擬內存使用
在應用進程進行內存映射mmap(將文件映射到內存)或者文件讀寫時,虛擬內存會先訪問頁緩存,找不到就會出現缺頁中斷,觸發對文件系統的查詢,而後再把數據加載到頁緩存
不少文件操做都須要搜索文件,爲了保證只在第一次讀取的時候搜索,操做系統須要在第一次訪問的時候打開文件,返回一個文件描述符,文件描述符就是一個索引,指向打開文件表中的打開文件,操做系統在該打開文件中維護了一些狀態信息,保證之後在操做該文件的時候無需再次搜索
操做系統會建立一個全局打開文件表,同時也會爲每一個進程建立一個打開文件表,其中維護了這些信息:
讀取一個文件的流程:
多個進程打開文件的時候,可能會出現併發安全問題
操做系統提供了兩種文件鎖:
當文件須要磁盤空間的時候,文件系統須要爲該文件分配數據塊
經常使用分配算法:
分配的時候主要考慮兩點:
根據文件須要的塊大小,查找磁盤中空閒塊,發現有足夠大小的,就分配給文件
優勢:
缺點:
根據文件須要的塊大小,找到磁盤中各個空閒塊進行分配,並經過鏈表指針聯繫到一塊
優勢:
缺點:
根據文件須要的塊大小,找到磁盤中的空閒塊進行分配,並單獨利用一個塊存儲索引這些數據塊
優勢:
缺點:
實際unix文件系統(UFS)會結合索引分配和鏈式分配組成多級索引分配算法
要爲文件分配數據塊,首先得知道全部空閒塊在哪。先來看幾種空閒塊管理機制:
位圖:用位圖表示全部塊,0表示空閒,1表示已分配
鏈表:在一個空閒塊中加入指針指向下一個空閒塊,造成鏈表。
索引:經過一個塊存儲索引,記錄這些空閒塊的位置
實際系統是組合這幾種方式
機械硬盤都是經過磁頭進行磁盤尋址,若是磁盤越大,尋址時間越大。因此將磁盤劃分紅多個分區能夠減小尋址時間,提高磁盤訪問速度,可是若是同時在多個分區之間切換也會帶來性能的降低
分區就是一組柱面的集合,每一個分區能夠視爲一個獨立的磁盤
分區組織方式:
其中第二種方式,在一個分區使用多塊磁盤,能夠基於此方案提高文件系統的可靠性與吞吐量,利用到的就是磁盤冗餘技術
基於上述第二種方案,能夠利用冗餘磁盤提升吞吐量(並行)與可靠性(冗餘)
磁盤冗餘陣列簡稱RAID,是一種基於冗餘磁盤的思想實現的磁盤管理技術,經常使用的有RAID-0,RAID-1,RAID-5等
能夠經過文件系統或者RAID硬件控制器來實現
將數據塊分紅多個小塊,並行存儲在獨立的磁盤上,這種方案能夠提高吞吐量
向兩個盤寫,從任意一個讀,利用其中一個作鏡像盤來提升可靠性。這種基於冗餘盤的思想同時緩解了一個盤的讀壓力,至關於也會提高讀性能
利用一個盤作校驗盤,其餘盤基於RAID-0的方案拆分小塊的基礎上並行訪問,校驗盤的數據是其餘盤數據的校驗和。這種方案能夠保證即便其中一個數據盤壞了,也能基於校驗和和剩餘磁盤來恢復它的數據。同時由於利用到了RAID-0的並行方案,也提高了讀寫性能
與RAID-4思想一致,可是爲避免校驗盤稱爲瓶頸,取消惟一的校驗盤,在每次數據寫入時,將計算好的校驗和輪流存放在全部磁盤上,造成一個分佈式系統的負載均衡算法
RAID-4和RAID-5都是基於塊計算校驗和,而RAID-3是基於位來計算校驗和
RAID-5每次寫都會計算出一個校驗塊,保證最終能夠容忍一個磁盤壞掉。RAID-6則是計算出兩個校驗塊,保證能夠容忍兩個盤壞掉
RAID嵌套技術之一
讓兩個磁盤採用RAID-0方案並行讀寫,再利用兩個盤做爲鏡像盤同步數據。安全性、性能較好,成本較高
RAID嵌套技術之一
讓兩個盤採用RAID-1方案一個主一個備,再利用兩個盤一主一備,先後二者採用RAID-0的方案並行讀寫。安全性、性能較好,成本較高
能夠分爲三類:
各設備有不一樣的I/O實現。根據cpu與這些設備的交互,將I/O分爲阻塞I/O、非阻塞I/O、異步I/O
用戶進行讀寫操做後,須要等待設備完成讀寫操做,並返回結果
用戶進行讀寫操做後,不須要等待返回結果
用戶進行讀寫操做後,不須要等待返回結果,可是操做系統完成讀寫操做後會通知用戶
cpu經過北橋與內存、顯卡等高速設備鏈接,經過南橋與I/O等設備鏈接
cpu依賴I/O設備控制器與I/O設備交互,設備控制器結構爲:
cpu與I/O設備交互的三種方式:
cpu經過I/O端口訪問I/O設備
MMU將I/O設置的存儲地址映射到內存,cpu經過訪問內存來實現對I/O設備的訪問
I/O訪問流程就是從用戶進程上到下的訪問流程,當完成訪問後設備經過中斷,從下到上通知用戶進程
cpu和I/O設備之間基於兩種方式交換數據:
程序I/O:直接經過cpu指令控制I/O設備交互數據
DMA:cpu讓I/O設備經過DMA直接讀寫內存,cpu訪問內存便可獲得這些數據
完成數據傳輸後,設備須要通知cpu,有兩種機制:
輪詢:cpu輪詢控制器寄存器,獲取設備狀態信息,根據狀態進行操做
中斷:設備經過中斷將事件反應給cpu。cpu每執行一條指令後都會進行中斷檢查,發現中斷後立馬執行中斷請求,而後再恢復執行原來的進程
設備控制器直接訪問內存的一種機制
基於DMA和中斷的方式讀取磁盤數據的流程:
磁盤工做機制
讀取數據其實就是磁頭定位到指定的磁道,而後從磁道讀取指定扇區的內容
尋道時間:磁頭定位到磁道所花的時間
旋轉延遲:在磁頭定位到磁道後,磁盤不斷旋轉,直到磁頭髮現數據所在扇區,這個時間開銷就是旋轉延遲
磁盤I/O傳輸時間=等待設備可用+等待傳輸通道可用+尋道時間+旋轉延遲+數據傳輸時間
是一種優化尋道時間的算法,基於如下前提,該算法纔有意義:
當大量隨機I/O請求到來時,磁頭會前後指向不一樣的磁道,致使尋道開銷較大,使用一種優化的順序減小磁頭須要「走動的距離」,是調度算法須要考慮的
優先服務先來的I/O請求
優勢:
缺點:
優先處理從當前磁臂移動距離最短的I/O請求
優勢:
缺點:
掃描算法,也成電梯算法,先從一個方向處理全部I/O請求,到頭以後從另外一個方向處理剩餘I/O請求
這種算法緩解了SSTF中的飢餓狀況,可是仍是會出現某個方向磁道邊緣的I/O請求飢餓的狀況
循環算法,從一個方向處理全部I/O請求直到磁道盡頭,磁頭立刻移動到另外一端(中間不處理請求),沿着這個方向繼續處理全部請求
相比較SCAN,緩解了飢餓現象。保證磁道邊緣的請求也能很快獲得處理
C-SCAN會沿着一個方向處理I/O請求直到磁道盡頭,C-LOOK的優化是沿着一個方向處理I/O請求直到該方向沒有I/O請求,其餘都同樣
現代操做系統每每會結合這些算法進行使用,保證尋道時間短的同時,又不會出現請求飢餓的狀況
因爲訪問磁盤的速度和訪問內存的速度查了幾個量級,因此須要使用磁盤緩存來緩解這個差別致使的瓶頸
這個緩存能夠採用單緩存和雙緩存
磁盤緩存須要一套置換算法來保證,常常用的扇區數據被緩存,少用的被置換到磁盤
這種算法結合了LRU和LFO的優勢進行處理,短週期的以LRU爲準,長週期的以LFO爲準