書《計算機操做系統》第四版(湯小丹編著)git
課程操做系統程序員
操做系統啓動流程略了github
md和pdf下載:Chasssser算法
完整版包括收集的題目shell
如下僅爲知識點數據庫
操做系統是配置在計算機硬件上的第一層軟件,是對硬件系統的首次擴充。其主要做用是管理好這些設備,提升他們的利用率和系統的吞吐量,併爲用戶和應用程序提供一個簡單的接口,便於用戶使用。(第一章第一段)編程
計算機系統中同時存在多個運行的程序,須要OS管理和調度。api
並行性:兩個或者多個事件在同一時刻發生。數組
併發性:兩個或者多個事件在同一時間間隔內發生。
「同時」訪問:有的資源容許一段時間內由多個進程"同時"對它們進行訪問,"同時"在微觀上意義上,進程對該資源的訪問是交替進行的。
互斥共享:有的資源雖然能夠供給多個進程使用,可是一段時間內只容許一個進程訪問該資源,故創建進程對這類資源的互斥訪問。
利用多道程序設計技術,讓每一個用戶都以爲有一個計算機專門爲他服務
時分複用:利用某設備爲一用戶服務的空閒時間內,又轉去爲其餘用戶服務。經過利用處理機的空閒時間運行其它程序,提升處理的利用率
空分複用:利用存儲器的空閒空間分區域存放和運行其餘的多道程序,以此提升內存的利用率。
程序的執行不是一向到底,而是走走停停,向前推動的速度不可預知,這就是進程的異步性。
可是隻要運行環境相同,OS須要保證程序運行的結果也要相同
進程控制:爲做業建立進程、撤銷(終止)已結束的進程、控制進程在運行過程當中的狀態轉換
進程同步:爲多個進程(線程)的運行進行協調。
進程通訊:實現相互合做進程之間的信息交換。
內存分配
內存保護
地址映射
內存擴充
緩衝管理:緩和CPU和I/O設備速度不匹配的矛盾。
設備分配:設備控制表、控制器控制表
設備處理:設備驅動程序,實現CPU和設設備控制器之間的通訊。
文件存儲空間的管理
目錄管理
文件的讀/寫管理和保護
用戶接口
程序接口
系統安全
網絡的功能和服務
支持多媒體
■ 操做系統=裝載器+通用子程序庫
■ 問題:昂貴組件的低利用率
■ 順序執行與批處理
■ 主要缺點:系統中的資源得不到充分利用,由於內存中只有一道程序
■ 保持多個工做在內存中而且在各工做間複用CPU
■ 多道程序交替執行,交替的條件是前一個正在執行的程序主動讓出CPU的使用權。
■ 多道批處理系統主要考慮的是系統效率和系統的吞吐量(優勢)。
■ 多道批處理系統缺點:平均週轉時間長,無交互能力
■ 定時中斷用於工做對CPU的複用
■ 交互性和及時性是分時系統的主要特徵。
■ 實時系統的正確性,不只有計算的邏輯結果來決定,還取決於產生結果的時間。
■ 實時任務的類型:
週期性實時任務和非週期性實時任務,前者是指外部設備週期性地發出激勵信號給計算機,使其週期性執行,以便週期性地控制某外部設備,後者無明顯的週期性,可是都必須聯繫着一個截止時間。
硬實時和軟實時,前者必須知足對截止時間的要求,後者對此沒有嚴格要求
無結構
模塊化
分層
自底向上的分層原則,肯定每一步的設計都是創建在可靠的基礎上。
微內核結構
只將最基本的部分放入微內核中。
防止OS自己及相關數據遭到應用程序或無心的破壞,一般將處理機的執行狀態分爲:
系統態(內核態,內核態又稱爲管態):高權限,能訪問全部的寄存器。
用戶態:低權限,能訪問指定的寄存器。
例子:
CPU執行操做系統代碼的時候稱爲處理機處於管態。
函數調用並不會切換到內核態,而除零操做引起中斷,中斷和系統調用都會切換到內核態進行相應處理。
計算機的一些功能只有內核有權利訪問,經過中斷、異常和系統調用爲應用程序提供方便。
在計算機運行中,內核是被信任的第三方
只有內核能夠執行特權指令
方便應用程序
當外設鏈接計算機時,會出現什麼現象?(中斷)
當應用程序處理意想不到的行爲時,會出現什麼現象?(異常)
經過調用函數庫,函數庫又會調用對應的系統調用接口,從而獲得系統服務。
系統調用時會有堆棧切換和特權級的轉換,INT和IRET用於系統調用。
功能調用時沒有堆棧切換,CALL和RET用於功能調用。
咱們要解決用戶程序如何來解決系統的服務。就好象說咱們提供給銀行對外提供服務,銀行爲了保證安全,它有不少的防禦,這個防禦又和對外提供服務這是有矛盾的。
爲了方便用戶來使用銀行的服務,應該必須提供靈活的訪問接口,又不能影響到銀行的安全。
操做系統內核也是同樣的,咱們須要來經過系統調用來提供一個接口,讓應用程序既方便的使用內核提供的服務,又不至於用戶的行爲對我內核的安全產生影響
硬件處理
在CPU初始化時設置 中斷使能 標誌
註釋:1)在許可外界打擾CPU的執行以前,CPU是不會對外界的任何中斷請求發出響應的。
2)生成中斷標誌,一般是一個電平的上升沿或者說是一個高電平,CPU會記錄這個事件。
我有一箇中斷標誌,表示出現了一箇中斷,什麼設備產生的,須要知道中斷源的編號。
軟件
現場保持 (編譯器)
中斷服務處理 (服務例程)
清除中斷標記 (服務例程)
現場恢復 (編譯器)
注: 都到了中斷向量表,中斷--中斷服務例程,異常--異常服務例程,系統調用--總共佔有一箇中斷編號,不一樣系統調用功能由系統調用表來表示的。由系統調用表的不一樣,選中不一樣的系統調用實現。
若是是系統調用,因爲系統調用的量很大,他在中斷向量表裏只佔一箇中斷編號,不一樣的系統調用的功能由系統調用表實現。
須要保存上下文信息。
我正在處理一個請求的時候,又來了一個請求這時候我怎麼辦,那咱們說在操做系統的裏頭呢?
它是硬件的中斷,它是容許被打斷的,也就是說我正在處理一箇中斷的時候,能夠容許你再出現其餘的中斷。
若是兩個中斷源不一樣,那這時候我能夠經過優先級的高低,讓一個日後推一段,或者說讓一個暫停下來,那使得我能夠同時在作交替在作處理。
中斷服務例程裏頭,並非說我任何一個時刻均可以作任何一個處理,它會在必定的時間裏禁止中斷請求。
好比說我電源有問題,那可能其餘的問題就變得不重要了,這時候我在作電源的處理的時候,我就會禁止掉其餘中斷。中斷服務請求會一直保持到CPU作出響應。
好比說我在這裏頭虛擬存儲裏頭,它訪問到的存儲單元的數據不存在,我正在從硬盤上倒數據進來。倒的過程中,它會用到磁盤I/O,這時候也會再有磁盤設備的中斷,這時候是容許它能夠作嵌套的。
系統調用是提供給應用程序使用的,由用戶態發出,進入內核態執行。外部中斷隨時可能發生;應用程序執行時可能發生缺頁;進程切換徹底由內核來控制。
進程是指一個具備必定獨立功能的程序在一個數據集合上的一次動態執行過程。
進程包含了正在運行的一個程序的全部狀態信息 :
內核選擇一個就緒的進程,讓它佔用處理機並運行
如何選擇?處理機調度算法
只有進程自己才知道什麼時候須要等待某種事件的發生,即致使其進入等待狀態的必定是進程自己內部緣由所致使的,不是外部緣由所致使的。
進程只能被別的進程或者操做系統給喚醒。
一個新進程被產生出來執行一個程序
當進程被建立完成並初始化後,一切就緒準備運行時,變爲就緒狀態
處於就緒狀態的進程被進程調度程序選中後,就分配處處理機上運行
當進程表示它已經完成或者因出錯,當前運行進程會由操做系統做結束處理(回收資源)
處於運行狀態的進程在其運行期間,因爲分配給它的處理時間片用完而讓出處理機
當進程請求某資源且必須等待時
當進程要等待某事件到來時,它從阻塞狀態變到就緒狀態。
處在掛起狀態的進程映像在磁盤上,目的是減小進程佔用內存
進程在外存並等待某事件的出現(多加了一個關於進程的位置信息)
進程在外存,但只要進入內存,便可運行
(沒法進入內存緣由:內存空間不夠或者進程自己優先級不夠高)
沒有進程處於就緒狀態或者就緒進程要求更多內存資源
當有高優先級等待(系統認爲會很快就緒的)進程和低優先級就緒進程
對搶先式分時系統,當有高優先級等待掛起進程由於事件出現而進入就緒掛起(好比內存不夠)
當有等待掛起進程由於相關事件出現
沒有就緒進程或者掛起就緒進程優先級高於就緒進程
當一個進程釋放足夠內存,並有高優先級等待掛起進程
就緒隊列、各類等待隊列
進程狀態變化時,它所在的PCB會從一個隊列 換到另外一個
進程通訊是進程之間的信息交換,是進程進行通訊和同步的機制。
進程不借助任何共享存儲區或數據結構,而是以格式化的消息(message)爲單位,將數據封裝在消息中,並利用操做系統提供一組通訊命令(原語)完成信息傳遞和數據交換。
發送進程利用OS所提供的通訊指令,直接把消息放到目標進程
(1)對稱尋址方式;該方式要求發送和接受進程必須以顯示方式提供對方的標識符。
系統提供命令:
send(receiver,message);//發送一個消息給接受進程receiver receive(sender,message);//接受進程sender發來的消息
(2)非對稱尋址方式;在接受程序原語中,不須要命名發送進程。
系統提供命令:
send(P,message);//發送一個消息給接受進程P receive(id,message);//接受來自任何進程的消息,id變量能夠設置爲發送進程的id或者名字
(1)定長(消息長度)
(2)變長(消息長度)
(1)發送阻塞,接收阻塞
(2)發送不阻塞,接收阻塞
(3)發送不阻塞,接收不阻塞
創建方式:(1)顯示創建連接命令;(2)發送命令自動創建鏈路
通訊方式(1)單向(2)雙向
(增長了消息隊列的隊首指針,互斥和資源信號量)
發送原語首先根據發送區a中的消息長度a.size來申請一個緩衝區i,接着把a中的信息複製到緩衝區i中。得到接受進程內部標識符j,而後將i掛在j.mq上,因爲該隊列屬於臨界資源,因此執行insert先後都要執行wait和signal操做。
其中
mq//消息隊列 mutex//對消息隊列的互斥訪問 sm//消息的資源信號量
調用接受原語receive(b),從本身的消息緩衝隊列mq中摘下第一個消息緩衝區i,並將其中的數據複製到以b爲首地址的指定消息接收區內。
發送和 接收進程,經過共享中間實體(郵箱 )完成通訊。該實體創建在隨機存儲器的公用緩衝區上,用來暫存信息。
信箱頭:用於存放信箱的描述信息,如信箱標識符等
信箱體:由若干個能夠存放信息的信箱格組成,信箱格數目和大小是在建立信箱時肯定的。
(1)郵箱的建立和撤銷
(2)消息的發送和接收
Send(mailbox,message);//將一個消息發送到指定郵箱 Receive(mailbox,message);//從指定郵箱中接受一個消息
(1)私用郵箱:只有建立者才能接收消息
(2)公用郵箱:操做系統建立
(3)共享郵箱:建立進程指明接收進程
(1)一對一:專用通訊鏈路
(2)多對一:客戶/服務器
(3)一對多:廣播
(4)多對多:公共郵箱
其中
共享內存是把同一個物理內存區域同時映射到多個進程的內存地址空間的通訊機制
每一個進程都有私有內存地址空間
每一個進程的內存地址空間需明確設置共享內存段
同一進程中的線程老是共享相同的內存地址空間
快速、方便地共享數據;
最快的通訊方法;
一個進程寫另一個進程當即可見;
沒有系統調用干預;
沒有數據複製;
不提供同步,必須用額外的同步機制來協調數據訪問,好比由程序員提供同步
一個嵌套字就是一個通訊標識類型的數據結構,包含通訊目的的地址,端口號,傳輸層協議等
基於文件型:兩個進程都運行在同一臺機器上,嵌套字基於本地文件系統支持
基於網絡型:非對稱通訊方式,須要發送者提供接收者的命名
不只使用與同一臺計算機內部的進程通訊,並且適用於網絡環境中不一樣計算機之間的進程通訊。
在OS中引入進程是爲了讓多個程序能併發執行,來提升資源利用率和系統吞吐量。
在OS中映入線程是爲了減小程序在併發執行時所付出的時空開銷,使得OS有更高的併發性。
線程是進程的一部分,描述指令流執行狀態,它是進程中的指令執行流的最小單元,是CPU調度的基本單位。
調度的實質是一種資源分配,處理機調度是對處理機資源進行分配。
處理機調度決定系統運行時的性能:系統吞入量、資源利用率、做業週轉時間、做業響應時間等….
高級調度(又稱長程調度或者做業調度)-》做業級
低級調度(又稱短程調度或者進程調度)-》進程(線程)級
中級調度(內存調度)-》內存
在進程/線程的生命週期中的何時進行調度?
好比3個進程,計算時間爲12,3,3,到達順序爲P1,P2,P3(假設同一時刻到達)
則週轉時間=(12+15+18)/3=15
若是到達順序爲P2,P3,P1
則測試周轉時間=(3+6+18)/3=9
簡單
平均等待時間波動比較大,好比短進程可能排在長進程後面
選擇就緒隊列中執行時間最短的進程佔用CPU進入運行狀態
就緒隊列按照預期的執行時間長度來排序
新進程所須要的執行時間比當前正在執行的進程剩餘的執行時間還要短,那麼容許它搶先。
SPN算法中一組進程的平均週轉時間
此時週轉時間\(=(r_1+r_2+r_3+r_4+r_5+r_6)/6\)
修改進程執行順序可能減小平均等待時間嗎?
週轉時間\(=(r_1+r_2+r_4-c_3+r_5-c_3+r_4+c_4+c_5+r_6)/6\)
$=(r_1+r_2+r_3+r_4+r_5+r_6+(c_4+c_5-2c_3))/6$
\(c_i\)表示進程\(P_i\)的執行時間(不必定等於週轉時間)
選擇就緒隊列中響應比R值最高的進程
即按照R值來排序
R=(w+s)/s
w: 等待時間(waiting time) s: 執行時間(service time)
時間片結束時,按照FCFS算法切換到下一個就緒進程
每隔(n-1)個時間片進程,進程執行一個時間片q
進程在一個時間片內已執行完,馬上調度,並將該進程從就緒隊列中刪除
進程在一個時間片內未執行完,馬上調度,並將該進程放入就緒隊列末尾
如:前臺(交互)、後臺(批處理)
如:前臺–RR、後臺–FCFS
設置多個就緒隊列,爲每一個隊列賦予不一樣的優先級,每一個隊列採用FCFS算法,按隊列優先級調度
對多個進程在執行順序上進行調節,使併發執行的諸程序之間能按照必定的規則(時序)共享系統資源,並可以很好的相互合做,從而使程序的執行具備可再現性。
間接相互制約關係(互斥):因爲共享系統資源致使
直接相互制約關係(同步):爲完成同一任務而合做
好比打印機,磁帶機,producer-consumer問題
enter section //進入區 critical section //臨界區 exit section //退出區 remainder seciton//剩餘區
空閒讓進:無進程時,任何進程可進去
忙則等待:有進程在臨界區時,其餘進程均不能進入臨界區
有限等待:有點等待時間,不能無限等待
讓權等待(可選):不能進入臨界區的進程,應釋放CPU
軟件實現方法,硬件實現方法。
local_irq_save(unsigned long flags); //關中斷 critical section //臨界區 local_irq_restore(unsigned long flags); //使能中斷
知足線程\(T_i\)和\(T_j\)之間互斥的經典的基於軟件的方法
int turn; //表示容許進入臨界區的線程ID boolean flag[]; //表示進程請求進入臨界區
flag[i]=true; turn=j; while(flag[j] && turn == j); //有一個條件不知足就進入臨界區,不然一直等 /* *此時若是同時有兩個進程進入臨界區 *那麼先寫的那個進程能進入(後一個不知足),後的不能(都知足) */
flag[i]=false;
線程\(T_i\)的代碼
do{ flag[i]=true; //線程i請求進入臨界區 turn=j; while(flag[j] && turn == j); CRITICAL SECTION //臨界區 flag[i]=false; REMAINDER SECTION //退出區 }while(true);
flag[0]=false; flag[1]=false; turn=0; do{ flag[i]=true; //線程i請求進入臨界區 while(flag[j]==true){ if(turn!=i){ flag[i]=false; while(turn!=i){} flag=true; } } CRITICAL SECTION //臨界區 turn=j; falsg[i]=false; REMAINDER SECTION //退出區 }while(true);
基於硬件提供了一些同步原語,好比中斷禁用,原子操做指令等
操做系統提供更高級的編程抽象來簡化進程同步,例如:鎖、信號量,用硬件原語來構建
class Lock{ int value=0; } //忙等待鎖 Lock::Acquire(){ while(test-and-set(value)) ;//spin } Lock::Release(){ value=0; }
複雜,須要兩個進程間的共享數據項
須要忙等待,浪費CPU時間
信號量是操做系統提供的一種協調共享資源訪問的方法
由一個整形變量sem(共享資源的數目)和兩個原子操做組成
//P操做--申請使用資源 P()(Prolaag (荷蘭語嘗試減小)) -》wait sem--;//可用資源減小一 if sem<0,進入等待,不然繼續 //可用資源用完了,須要等待其餘線程釋放資源 //V操做--釋放可用資源 V()(Verhoog (荷蘭語增長)) -》signal sem++; if sem<=0,喚醒一個等待進程
不能。由於自旋鎖須要佔用CPU,隨時檢查,有可能臨界區的使用者退出時剛修改完,下一個進入者進入時資源才變成有效,就沒法實現先進先出。
classSemaphore{ int sem; //共享資源數目 WaitQueue q; //等待隊列 } Semaphore::P(){ sem--; if(sem<0){ //資源用完了 Add this thread t to q; block(p); //阻塞 } } Semaphore::V() { sem++; if (sem<=0) { //此時前面仍有等待線程 //從對應的等待隊列裏把相應的線程放入就緒隊列 Remove a thread t from q; wakeup(t); } }
每一個臨界區設置一個信號量,其初值爲1
mutex = new Semaphore(1); //信號量初始化爲1 //控制臨界區的訪問 mutex->P(); //信號量計數-- Critical Section; mutex->V(); //釋放資源,信號量計數++
注意:
初始化若是是同步互斥,看資源數目,若是是條件同步,爲0或者1
必須成對使用P()操做和V()操做
P()操做保證互斥訪問臨界資源
PV操做不能次序錯誤、重複或遺漏(但不要求P在V以前或者以後)
執行時不可中斷
問題:
不申請直接釋放,出現多個線程進入臨界區的狀況
只申請不釋放,緩衝區沒有線程,可是誰也進不去臨界區
//此時的條件同步設置一個信號量,初始化爲0 condition =new Semaphore(0); //實現一個條件等待,線程A要等到線程B執行完X模塊後才能執行N模塊 //線程A ---M--- condition->P(); ---N--- //線程B ---x--- condition->V(); ---Y--- //在B裏釋放信號量,使其0->1,若是B先執行完X模塊,則A能夠直接往下執行; //若是A先執行完就等待
有界緩衝區的生產者-消費者問題描述
問題分析
用信號量描述每一個約束
實現
Class BoundedBuffer { mutex = new Semaphore(1); fullBuffers = new Semaphore(0);//一開始緩衝區中沒有數據 emptyBuffers = new Semaphore(n);//全都是空緩衝區 }
BoundedBuffer::Deposit(c) {//生產者 emptyBuffers->P(); //檢查是否有空緩衝區 mutex->P(); //申請緩衝區 Add c to the buffer; mutex->V(); fullBuffers->V();//釋放該資源,相等於緩衝區中多了一個數據 }
BoundedBuffer::Remove(c) {//消費者 fullBuffers->P();//檢查緩衝區中是否有數據 mutex->P(); Remove c from buffer; mutex->V(); emptyBuffers->V();//釋放空緩衝區資源 }
兩次P操做的順序有影響嗎?
交換順序會出現死鎖,緣由在於自我檢查空和滿
管程是一種用於多線程互斥訪問共享資源的程序結構
管程的使用
控制管程代碼的互斥訪問
管理共享數據的併發訪問
若是是0個,就等同與一個臨界區,若是是多個就是管程所特有的
Class Condition{ int numWaiting=0; //條件變量初值爲0,若是在信號量裏和資源數目一致 WaitQueue q; }
Condition::Wait(lock){ numWaiting++; //等待數目++ Add this thread t to q;//將本身放入等待隊列當中 release(lock); //釋放管程的互斥訪問權限 shedule();//執行調度,切換線程need mutex require(lock);//請求訪問權限 }
Condition::Signal(){ if(numWaiting>0){//等待隊列不爲空,即有另外的線程等待這個條件變量上,每一個變量對應一個隊列 Remove a thread t from q;//將此線程從等待隊列移動到就緒隊列中 wakeup(t);//喚醒進程need mutex numWaiting--;//等待數目-- } }
classBoundedBuffer { … Lock lock;//一個入口等待隊列 int count = 0; //寫入緩衝區的數據的數目 Condition notFull, notEmpty;//兩個條件變量 }
BoundedBuffer::Deposit(c) {//生產者 lock->Acquire(); //管程進入權申請 while (count == n) //n個緩衝區中都有數據了--對應**1 notFull.Wait(&lock);//就放棄管程使用權,等在notfull條件變量上 Add c to the buffer; count++; notEmpty.Signal(); lock->Release(); //管程進入權釋放 }
BoundedBuffer::Remove(c) {//消費者 lock->Acquire(); //管程進入權申請 while (count == 0) //若是沒數據 notEmpty.Wait(&lock);//就放棄管程使用權,等在非空條件上 Remove c from buffer; count--; notFull.Signal(); //讀出一個數據後就釋放notfull--對應**1 lock->Release(); //管程進入權釋放 }
1.初始化
2.管程中寫法
5個哲學家圍繞一張圓桌而坐,桌子上放着5支叉子,每兩個哲學家之間放一支
哲學家的動做包括思考和進餐,進餐時需同時拿到左右兩邊的叉子,思考時將兩支叉子放回原處
如何保證哲學家們的動做有序進行?如:不出現有人永遠拿不到叉子
#define N 5 // 哲學家個數 semaphore fork[5]; // 信號量初值爲1 void philosopher(int i) // 哲學家編號:0 - 4 while(TRUE) { think( ); // 哲學家在思考 if (i%2 == 0) { P(fork[i]); // 去拿左邊的叉子 P(fork[(i + 1) % N]); // 去拿右邊的叉子 } else { P(fork[(i + 1) % N]); // 去拿右邊的叉子 P(fork[i]); // 去拿左邊的叉子 } eat( ); // 吃麪條中…. V(fork[i]); // 放下左邊的叉子 V(fork[(i + 1) % N]); // 放下右邊的叉子 } //沒有死鎖,可有多人同時就餐
用信號量描述每一個約束
semphoare WriteMutex=1; int Rcount=0; semphoare CountMutex=1;
void Writer(){ P(WriteMutex); write; V(WriteMutex); }
void Reader(){ P(CountMutex); if (Rcount == 0) P(WriteMutex); ++Rcount; V(CountMutex); read; P(CountMutex); --Rcount; if (Rcount == 0) V(WriteMutex); V(CountMutex) } //此實現中,讀者優先
讀者優先策略
只要有讀者正在讀狀態,後來的讀者都能直接進入
如讀者持續不斷進入,則寫者就處於飢餓
寫者優先策略
只要有寫者就緒,寫者應儘快執行寫操做
如寫者持續不斷就緒,則讀者就處於飢餓
如何實現?
用信號量描述每一個約束
semaphore WriteMutex=1,ReadMutex=1,x=1; int Rcount=0,WRcount=0; semaphore CountMutex=1,WRMutex=1;
void Reader(){ P(x); P(ReadMutex); P(CountMutex); if(Rcount==0) P(WriteMutex); ++Rcount; V(CountMutex); V(ReadMutex); V(x); read; P(CountMutex); Rcount--; if(Rcount==0) V(WriteMutex); V(CountMutex); }
void Writer(){ P(WRMutex); if(WRcount==0) P(ReadMutex); WRcount++; V(WRMutex); P(WriteMutex); Write; V(WriteMutex); P(WRMutex); WRcount--; if(WRcount==0) V(ReadMutex); V(WRMutex); }
頂點
有向邊
若是一組進程中每個進程都在等待僅由該組進程中的其它進程才能引起的事件,那該組進程是死鎖的。
確保系統永遠不會進去死鎖狀態
預防是採用某種策略,限制併發進程對資源的請求,使得系統在任什麼時候刻都不知足死鎖的必要條件(四個)
在使用前進行判斷,只容許不會出現死鎖的進程請求資源
在檢測到運行系統進入死鎖狀態後,進行恢復
一般操做系統忽略死鎖,大多數操做系統(包括UNIX)的作法
在死鎖避免方法中,把系統的狀態分爲安全狀態和不安全狀態。
當系統處於安全狀態時,能夠避免發生死鎖。反之,可能發生死鎖。
系統處於安全狀態,必定沒有死鎖
系統處於不安全狀態,可能出現死鎖,避免死鎖就是確保系統不會進入不安全狀態
\(n\) = 線程數量, \(m\) = 資源類型數量
\(Max\)(總需求量):$ n×m$矩陣
線程\(T_i\)最多請求類型\(R_j\)的資源$ Max[i,j] $個實例
\(Available\)(剩餘空閒量):長度爲\(m\)的向量
當前有 $Available[j] \(個類型爲\)R_j$的資源實例可用
\(Allocation\)(已分配量):\(n×m\)矩陣
線程$T_i \(**當前分配**了\) Allocation[i, j] \(個\)R_j$的實例
\(Need\)(將來須要量):\(n×m\)矩陣
線程$T_i $將來須要 \(Need[i, j]\)個\(R_j\)資源實例
知足公式:
\(Need[i,j]= Max[i,j]–Allocation[i,j]\)
\(Request_i\) 線程\(T_i\)的資源請求向量
\(Request_i[j]\) 線程\(T_i\)請求資源\(R_j\)的實例
1.若是 \(Request_i ≤ Need[i]\), 轉到步驟2。不然, 拒絕資源申請, 由於線程已經超過了其最大要求
2.若是\(Request_i≤ Available\), 轉到步驟3。不然,\(T_i\)必須等待,由於資源不可用
3.經過安全狀態判斷來肯定是否分配資源給\(T_i\) :
生成一個須要判斷狀態是否安全的資源分配環境
\(Available= Available -Request_i\);//剩餘-請求
\(Allocation[i]=Allocation[i]+Request_i\);//已分配+請求
\(Need[i]=Need[i]–Request_i\);//將來須要-請求
若是返回結果是安全,將資源分配給\(T_i\)
若是返回結果是不安全,系統會拒絕\(T_i\)的資源請求
1.Work 和Finish 分別是長度爲m和n的向量初始化: Work = Available //當前資源剩餘空閒量 Finish[i] = false for i:1,2, …, n. //線程i沒結束 2.尋找線程Ti: (a) Finish[i] = false//接下來找出Need比Work小的線程i (b) Need[i]≤Work 若找到,執行3; 沒有找到知足條件的Ti,轉4。 3.Work = Work + Allocation[i]//線程i的資源需求量小於當前剩餘空閒資源量, 因此配置給它的資源再回收 Finish[i] = true 轉2 4.如全部線程Ti知足Finish[i] == true,//全部線程的Finish爲True,代表系統處於安全狀態 則系統處於安全狀態
容許系統進入死鎖狀態
維護系統的資源分配圖
按期調用死鎖檢測算法來搜索圖中是否存在死鎖
出現死鎖時,用死鎖恢復機制進行恢復
將內存中暫時不能運行的程序調到磁盤的對換區,同時將磁盤上能運行的程序調入內存
總體對換(進程對換),以進程爲單位,須要系統支持功能對對換空間的管理,進程的換入和進程的換出
頁面(分段)對換,以進程的一個頁面或者分段爲單位,有稱部分對換,其目的是支持虛擬存儲系統
文件區用於存放各種文件,對換區用於存放從進程換出的進程
實現從邏輯地址到物理地址的變換,藉助頁表來完成
從進程發出指定邏輯地址的訪問請求,通過地址變換,到內存中找到對應的實際物理單元取出數據的總時間。
主要知足用戶和程序員如下需求:
用戶把本身的做業按照邏輯管理劃分爲若干段,每一個段都是從0開始編址,並有本身的名字和長度。所以,但願要訪問的邏輯地址是由段名(段號)和段內偏移量(段內地址)決定的。
在實現對程序和數據的共享時,是以信息的邏輯單位爲基礎的。分頁系統中的頁只是存放信息的物理單位(塊),並沒有完整的意義,段倒是信息的邏輯單位。爲了實現段的共享,但願存儲管理能與用戶程序分段的組織方式相適應。
有些段,會隨着程序的使用不斷增加。而事先又沒法確切地知道數據段會增加到多大。
動態連接是指在做業運行前,並不把幾個目標程序段連接起來。要運行時,先將主程序所對應的目標程序裝入內存並啓動運行,當運行過程當中有須要調用某段時,纔將該段調入內存並進行連接。可見動態連接也要求以段做爲管理的單位。
段號+段內地址
段號可算一個做業最長有多少個段,段內地址可算每一個段的最大長度
在分段存儲管理方式中,做業的地址空間被劃分爲若干個段,每一個段定義了一組邏輯信息
在系統中爲每一個進程創建一段映射表,簡稱「段表」。每一個段在表中佔有一個表項。其中記錄了該段在內存中的起始地址(基址)和段的長度。段表能夠存放在一組寄存器中,以提升訪問速度,但更常見的是將段表放在內存中。
在配置了段表後,執行中的進程可經過查找段表找到每一個段所對應的內存區。
段表是用於實現從邏輯段到物理內存區的映射。
爲了實現進程邏輯地址到物理地址的變換功能,在系統中設置了段表寄存器,用於存放段表起始地址和段表長度TL。在進行地址變換時,系統將邏輯地址中的段號S與段表長度TL進行比較。若S>TL,表示段號太大。訪問越界,因而產生越界中斷信號;若未越界,則根據段表的起始地址和該段的段號+段內地址從而到的要訪問的內存物理地址。
段表放在內存中時,每次訪問一個數據都要兩次方寸,解決方法和分頁系統相似,設置一個聯想寄存器,來保存最近經常使用的段表項。
a)、頁是信息的物理單位,分頁是爲實現離散分配方式,其目的是消減內存的外零頭,提升內存的利用率;分段中的段則是信息的邏輯單位,它含有一組其意義相對完整的信息,分段的目的是爲了能更好地知足用戶的須要。
b)、頁的大小固定且由系統決定,由系統把邏輯地址劃分爲頁號和頁內地址兩部分,是由機器硬件實現的,於是在系統中只能有一種大小的頁面;而段的長度卻不固定,決定於用戶所編寫的程序,一般由編譯程序在對源程序進行編譯時,根據信息的性質來劃分。
c)、分頁的做業地址空間是一維的,分頁徹底是系統行爲,即單一的線性地址空間,程序員只需利用一個記憶符,便可表示一個地址;而分段的做業地址空間則是二維的,分段是用戶行爲,程序員在標識一個地址時,既要給出段名,又要給出段內地址。
先將用戶程序分段,在段內進行分頁,爲每個段賦予一個段名。在段頁式系統中,其地址結構由段號、段內頁號及頁內地址三部分所組成。
配置一個段表寄存器,其中存放段表起始地址和段表長TL。比較段號與TL是否越界,從段表寄存器中獲取段表始址找到段表,根據段表內的頁表始址找到對應的頁表,在根據頁表的存儲塊找到內存中的物理塊,從而獲取物理地址。
段頁式系統中,爲了得到一條指令或數據,須三次訪問內存:
① 訪問內存中的段表,從中取得頁表始址
② 訪問內存中的頁表,從中取出該頁所在的物理塊號,並與頁內地址造成物理地址
③ 訪問真正從第二次訪問所得的地址中,取出指令或者數據
屢次訪問內存,執行速度下降,所以在地址變換機構中增設一個高速緩衝寄存器。每次訪問它時,都須同時利用段號和頁號去檢索高速緩存,若找到匹配的表項,即可以從中獲得相應頁的物理塊號,用來與頁內地址一塊兒造成物理地址;若未找到匹配表項,則仍須要再三次訪問內存。
在可變分區存儲管理下,按地址排列的內存空閒區爲:100KB、500KB、200KB、300KB和600KB。現有若干用戶程序,其所需內存依次分別爲212KB、417KB、112KB和426KB,分別用首次適應算法、最佳適應算法、最壞適應算法,將它們裝入到內存的哪些空閒分區?哪一個算法能最有效利用內存?
可變分區存儲管理中,做業的撤離一定會修改內存的「空閒區表」,試畫出因做業撤離修改「空閒區表」的四種狀況。
根據回收區的首地址,在空閒分區表(鏈)找到插入點,此時可能出現4種狀況之一(假設空閒分區表按地址從低到高順序排列):
解:
在採用頁式存儲管理的系統中,某做業的邏輯地址空間爲4頁(每頁4096字節),且已知該做業的頁表以下表。試求出邏輯地址14688所對應的物理地址。
程序在執行時出現的局部性規律,即在一較短期內,程序的執行僅僅侷限於某個部分,相應地,它所訪問的存儲空間也侷限與某個區域。
空間侷限性:程序在一段時間內所訪問地址可能集中在必定的範圍內,其典型狀況是程序的順序執行
時間侷限性:程序中的某條指令(數據)被執行(訪問),不久後該指令可能再次被執行(訪問)。產生的典型緣由是在程序中存在大量的循環操做。
虛擬存儲器,是指具備請求調入功能和置換功能,能從邏輯上對內存容量加以擴充的一種存儲器系統。
程序被容許分紅屢次裝入內存
容許將暫不使用的代碼和數據從內存中調至外存的對換區
能從邏輯上擴充內存容量,使得用戶看到的內存容量遠大於實際內存容量
在分頁系統的基礎上增長了請求調頁功能和頁面置換功能所造成的頁式虛擬存儲系統,容許用戶程序只裝入少數頁面的程序和數據便可啓動運行,經過上述功能將即將運行的頁面調入內存,同時將暫不運行的頁面換出到外存。
在純分頁的頁表機制上增長其餘字段造成的數據結構,用於將邏輯地址轉換爲物理地址
每當用戶程序須要的頁面再也不內存中,就產生缺頁中斷
選擇的被淘汰頁面是之後永遠不使用的,或者是在最長(將來)時間內再也不被訪問的
老是淘汰最早進入內存的頁面,即選擇在內存中駐留時間最久的頁面進行淘汰
選擇最近最久未使用的頁面進行淘汰
LRU須要爲每一個內存頁面配置一個移位寄存器,來記錄進程在內存中的各個頁面使用狀況
LRU還須要用一個特殊的棧來保存當前使用的各個頁面的頁面號
請求分段系統中,程序在運行以前,只須要調入少數幾個分段(沒必要調入全部的分段)就能夠啓動運行。當所訪問的段不在內存中時,可請求OS將所缺的段調入內存。
在請求分段式管理中所須要的主要數據結構是請求段表
每當發現程序要訪問的斷再也不內存中,就有缺段中斷機構產生一箇中斷信號,由OS將所需段調入內存。
在一條指令的執行期間產生和處理中斷,可能發生屢次中斷,但不可能出現一條指令被分割在兩個段中。
被訪問的段再也不內存時,須要地址變換。具體作法是先將所缺的段調入內存,並修改段表,而後利用段表進行地址變換。
記錄了共享段的段號,段長,內存起始地址,狀態(存在位),外村起始地址,共享進程計數(count)
當第一個使用共享段的進程提出請求時,由系統爲該共享段分配一物理區,並調入該共享段,同時修改相應的段表(該段的內存地址)和共享段表,把 count 置爲 1。當其它進程須要調用此段時,不需再調入,只需修改相應的段表和共享段表,再執行 count :=count+1 操做。
當共享共享段的某進程再也不使用該共享段時,修改相應的段表和共享段表,執行 count :=count-1 操做。當最後一共享此段的進程也再也不須要此段時,則系統回收此共享段的物理區,同時修改共享段表(刪除該表項) 。
先利用段表寄存器中的段表長度與邏輯地址中的段號比較,若段號超界則產生越界中斷。
再利用段表項中的段長與邏輯地址中的段內位移進行比較,若段內位移大於段長,也會產生越界中斷。
注:在容許段動態增加的系統中,容許段內位移大於段長。
在段表中設置存取控制字段,用於規定對該段的訪問方式。
環保護機構是一種功能較完善的保護機制。在該機制中規定:低編號的環具備高優先權。
OS 核心處於 0 環內;某些重要的實用程序和操做系統服務佔居中間環;而通常的應用程序則被安排在外環上。
在環系統中,程序的訪問和調用應遵循必定的規則:
同時在系統中運行的進程太多,由此分配給每個進程的物理塊太少,不能知足進程正常運行的基本要求,使得每一個進程在運行時,頻繁地出現缺頁,必須請求系統調頁,這樣使得進程大部分時間用於頁面置換,處理機效率急劇降低。
在一個請求分頁存儲管理系統中,進程P共有5頁,頁號爲0至4。若對該進程頁面的訪問序列爲3,2,1,0,3,2,4,3,2,1,0,4,試用最佳(Optimal)置換算法、LRU置換算法和FIFO置換算法,計算當分配給該進程的物理塊數爲3時,訪問過程當中發生的缺頁次數和缺頁率。
獨佔設備,進程互斥地訪問這類設備,即系統一旦將該類設備分配給某進程,便由該進程獨佔,直到用完釋放。
共享設備,指一段時間內容許多個進程同時訪問的設備
一種按照字節交叉工做的通道,不適用於鏈接高速設備,一般含有許多非分配型子通道,每一個子通道鏈接一個I/O設備,這些子通道按照時間片輪轉方式共享主通道。
能夠鏈接多臺高速設備,但只含有一個分配型子通道,在一段時間內只能執行一道通道程序,控制一臺設備進行數據傳送,直到程序釋放通道。利用率很低,可是傳輸效率很高。
數組多路通道結合了數組選擇通道和字節多路通道,能使得各個子通道(設備)分時並行操做,含有多個非分配子通道。
用於實現CPU和設備控制器之間的通訊,該接口含有三類信號線:數據線,地址線和控制線
用於鏈接一個或者多個設備
用於實現對設備的控制
在多道程序中,利用一道程序模擬脫機輸入時的外圍控制機功能,再利用另外一道程序模擬脫機輸出時外圍控制機的功能,從而在主機的直接控制下,實現脫機輸入輸出。
在聯機狀況下實現的同時外圍操做的技術,即爲SPOOLing技術,假脫機技術。
指的是把磁頭移動到指定磁道上花費的時間,該時間是啓動磁頭的時間\(s\)和磁頭移動\(n\)條磁道所花費的時間之和,即爲
\(T_s=m*n+s\)
其中m爲一個常速,與磁盤驅動器的速度有關,通常磁盤,m爲0.2;高速磁盤,m<=0.1
指的是指定扇區移動到磁頭下所花費的時間
好比硬盤爲15000 r/min,則每轉須要4ms,從而平均旋轉延時\(T_τ\)爲2ms
指的是把數據從磁盤讀出或者向磁盤寫入數據所花費的時間,其大小和每次讀寫的字節數b和旋轉速度有關:
\(T_t=\frac{b}{r*N}\)
其中r爲磁盤每秒的轉速,N爲一條磁道上的字節數
當一次讀寫的字節數至關於半條磁道上的字節數時,\(T_t\)和\(T_τ\)相同,所以,可將訪問時間\(T_a\)表示爲:
\(T_a=T_s+\frac{1}{2r}+\frac{b}{rN}\)
根據進程請求訪問磁盤的前後順序進行調度
選擇這樣的進程,其要求訪問的磁道與當前磁頭所在磁道距離最近,使得每次的尋道時間最短,可是不能保證平均尋道時間最短
不只考慮將要訪問的磁道和當前磁道間的距離,更優先考慮的是磁頭當前的移動方向。
好比,當磁頭向外移動時,SCAN算法考慮的下一個磁道應該是當前移動方向上距離最近的,直到最後再反向移動
規定磁頭單向移動,當磁頭移動到最外磁道並訪問後,磁頭當即返回到最裏面的欲訪問磁道,即將最小磁道號和最大磁道號構成循環進行掃描
例題:假設一個磁盤的每一個盤面上有200個磁道,現有多個進程要求對存儲在該盤面上的數據進行訪問,按照這些請求到達的前後次序,它們的訪問位置分別處於5四、5七、3九、1八、90、16二、15四、3八、180號磁道上。假定當前磁頭在100號磁道上。請給出按「先來服務(FCFS)」、「最短尋道時間優先(SSTF)」和「掃描(SCAN)」算法進行磁盤調度時各自實際的訪問次序,並計算它們的平均尋道長度。(注:當採用掃描算法時,規定當前磁頭正在向磁道號增長的方向上移動)
解:
FCFS算法訪問次序:5四、5七、3九、1八、90、16二、15四、3八、180 平均尋道長度:55.3 SSTF算法訪問次序:90、5七、5四、3九、3八、1八、15四、16二、180 平均尋道長度:27.1 SCAN算法訪問次序:15四、16二、180、90、5七、5四、3九、3八、18 平均尋道長度:26.8
數據項是最低級的數據組織方式,可分爲基本數據項和組合數據項
記錄是一組關於數據項的集合,用於描述一個對象在某方面的屬性
文件是指由建立者所定義的,具備文件名的一組相關元素的集合,可分爲有結構文件和無結構文件兩種,每一個文件都有文件屬性。
文件屬性
文件的邏輯結構,從用戶觀點出發看到的文件組織形式,即文件是由邏輯記錄組成,是用戶能夠直接處理的數據及其結構,獨立於文件的物理特性,又稱爲文件組織
文件的物理結構,又稱爲文件的存儲結構,指系統將文件存儲在外存上的存儲組織形式
爲了方便管理,含有三類信息
磁盤索引節點,每一個文件有惟一的磁盤索引節點,包含內容
內存索引節點,存放在內存中的節點,文件打開時,將磁盤索引節點拷貝到內次索引節點中,包含內容
外存的組織形式分爲連續組織方式,連接組織方式,索引組織方式
爲每一個文件分配一組相鄰接的盤塊
優勢:
缺點:
爲文件分配多個不連續的盤塊,經過每一個盤塊上的連接指針將同屬於一個文件的離散盤塊造成鏈表,由此造成連接文件。
優勢:
缺點:
連接方式:
爲每一個文件分配一個索引表(塊),把分配給該文件的全部盤塊號都記錄在表(塊)中,在創建一個文件時,只要在爲之創建的目錄項中填入指向改索引塊的指針。
優勢:
缺點:
爲每一個文件分配一個索引表(塊),把分配給該文件的全部盤塊號都記錄在表(塊)中,在創建一個文件時,只要在爲之創建的目錄項中填入指向改索引塊的指針。對於一個大文件,所分配的塊已滿,必須再分配一個索引塊。
優勢:
缺點: