操作系統(考研,面試,期末複習)- 持續更新

個人博客:http://uesugier11.gitee.io/uesugi-er11/

認識操作系統

操作系統目標及作用

現代計算機中的計算機硬件:輸入設備+輸出設備+存儲器+運算器+控制器

image-20200908184220320

  • 操作系統(Operating System,OS):是管理計算機硬件與軟件資源的系統軟件,也是計算機系統的內核與基石。
    • 操作系統處理管理與配置內存
    • 決定系統資源供需的優先次序
    • 控制輸入與輸出設備
    • 操作網絡與管理文件系統等基本事務
    • 提供一個讓用戶與系統交互的操作界面

操作系統的目標

  1. 方便性
  2. 有效性
  3. 可擴充性
  4. 開放性

操作系統的作用

  1. 作爲用戶與計算機硬件系統之間的接口:OS處於用戶與計算機硬件系統之間,用戶通過OS來使用計算機系統。image-20200909195136530
  2. 作爲計算機系統資源的管理者:管理計算機資源,這些資源包括CPU、內存、磁盤驅動器、打印機等。
  3. 實現了對計算機資源的抽象:爲其他軟件軟件提供服務,操作系統與軟件進行交互,以便爲其分配運行所需的任何必要資源。

操作系統發展過程

未配置操作系統計算機系統

  1. 人工操作
  2. 脫機輸入/輸出(Off-Line I/O)方式
    1. 脫機IO:事先將裝有用戶程序和數據的紙帶裝入紙帶輸入機,在一臺外圍機的控制下,把紙帶上的數據輸入到磁帶上。當CPU需要這些程序和數據時,再從磁帶上高速地調入內存;
    2. 聯機IO:在主機的直接控制下進行輸入/輸出的方式,稱爲聯機輸入/輸出(On-Line I/O)方式

單道批處理系統

  • 具體的工作過程是首先由監督程序將磁帶上的第一個作業裝入內存,並把運行控制權交給作業;該作業處理完時,又把控制權交給監督程序,再有監督程序把磁帶的第二個作業調入內存等等。可以看成是串行的。

  • 優點:解決人機矛盾和CPU與IO設備速度不匹配問題,提高系統資源的利用率和系統吞吐量。

  • 缺點:不能充分的利用系統資源,現很少使用。

多道批處理系統

  • 用戶所提交的作業先放在外存上,並排成一個對列(後備對列),由作業調度程序按照一定的算法,從後備對列中選擇若干個作業調入內存,使其共享CPU和系統中的各種資源。同時在內存中裝入若干程序,這樣可以在A程序運行時,利用其IO操作而暫停的CPU空擋時間,再調度另一道程序B運行,同樣可以利用B程序在IO操作時調用CPU空檔調用程序C運行,使用多道程序交替運行,始終保持CPU忙碌的狀態。
  • 優勢:資源利用率高,使CPU始終處於忙碌的狀態,提高內存的利用率,提高IO利用率;系統吞吐量大(CPU和其資源始終保持忙碌的狀態,僅在作業完成時或者運行不下去的時候才切換,系統開銷小)。
  • 缺點:平均週轉時間長,無交互能力。

分時系統(Time Sharing System)

分時系統概念

在一臺主機上連接了多個配有顯示器和鍵盤的終端並由此所組成的系統,該系統允許多個用戶同時通過自己的終端,以交互方式使用計算機,共享主機中的資源。

分時系統特徵

  1. 多路性:多用戶同時在各自終端上使用同一CPU。
  2. 獨立性:用戶可彼此獨立操作,互不干擾,互不混淆。
  3. 及時性:用戶在短時間內可得到系統的及時回答。
  4. 交互性:用戶與系統進行人機對話。

實時系統(Real Time System)

實時系統概念

系統能及時響應外部事件的請求,在規定的時間內完成對該事件的處理,並控制所有實時任務協調一致地運行。

實時系統的類型

  1. 工業(武器)控制系統
  2. 信息查詢系統
  3. 多媒體系統
  4. 嵌入式系統

實時任務的類型

  1. 週期性實行任務和非週期性實時任務。
  2. 硬實時任務和軟實時任務。

實時任務特徵

  1. **多任務:**由於真實世界的事件的異步性,能夠運行許多併發進程或任務是很重要的。多任務提供了一個較好的對真實世界的匹配,因爲它允許對應於許多外部事件的多線程執行。系統內核分配CPU給這些任務來獲得併發性。
  2. **搶佔調度:**真實世界的事件具有繼承的優先級,在分配CPU的時候要注意到這些優先級。基於優先級的搶佔調度,任務都被指定了優先級,在能夠執行的任務(沒有被掛起或正在等待資源)中,優先級最高的任務被分配CPU資源。換句話說,當一個高優先級的任務變爲可執行態,它會立即搶佔當前正在運行的較低優先級的任務。
  3. **任務間的通訊與同步:**在一個實時系統中,可能有許多任務作爲一個應用的一部分執行。系統必須提供這些任務間的快速且功能強大的通信機制。內核也要提供爲了有效地共享不可搶佔的資源或臨界區所需的同步機制。
  4. **任務與中斷之間的通信:**儘管真實世界的事件通常作爲中斷方式到來,但爲了提供有效的排隊、優先化和減少中斷延時,我們通常希望在任務級處理相應的工作。所以需要在任務級和中斷級之間存在通信。

操作系統的基本特徵

image-20200913173604664

併發(Concurrence)

  • 並行:指兩個或多個事件在同一時刻發生

  • 併發:指兩個或多個事件在同一時間間隔內發生

  • 具體地說:併發指在一段時間內宏觀上有多個程序在同時運行,但在單處理機系統中,每一時刻卻僅能有一道程序執行,故在微觀上這些程序是分時地交替執行。
    若計算機系統有多個處理機,這些可以併發執行的程序便可以被分配到多個處理機上,實現並行執行。即利用每一個處理機來處理一個可併發執行的程序。

  • 引入概念**【進程】**:指在系統中能獨立運行 並作爲資源分配的基本單位,它是由一組機器指令、數據和堆棧等組成的,是一個能獨立運行的活動實體。

  • 在一個沒有引入進程的系統中,屬於同一個應用程序的計算機程序和 I/O程序之間只能是順序執行,也就是計算機程序執行告一段落後,才允許I/O程序執行;反之,在程序執行I/O操作時,計算程序也不能執行。-----------爲計算程序和I/O程序分別建立一個進程(Process)後,這兩個程序就可以 併發執行。

image-20200913161252525

共享(Sharing)

  • 在OS環境下的資源共享或稱爲資源複用,指的是系統中的資源可供內存中多個併發執行的進程共同使用。 -------在宏觀上既限定了時間(進程在內存期間),也限定了地點(內存)。
  • 實現資源共享的兩種方式
    • 互斥共享方式:系統中的某些資源:如打印機、磁帶機等,雖然可以提供給多個進程(線程)使用,但是應規定在一段時間內,只允許一個進程訪問該資源。
      -------「臨界資源」:一段時間內只允許一個進程訪問的資源
    • 同時訪問方式:系統中還有另外一些資源,允許在一段時間內由多個進程「同時」對它們進行訪問。 ------這裏的「同時」也就是前面講的在微觀下交替進行的。
      典型的例子:磁盤設備!

**併發和共享是OS的兩個最基本的特徵!沒有併發和共享就談不上虛擬和異步; **

虛擬(Virtual)

虛擬和異步是依賴於併發特性的。

所謂虛擬(Virtual)是指通過某種技術把一個物理實體變成爲若干個邏輯上的對應物。
物理實體是實際存在的東西,邏輯實體是虛的,它並不存在,但是用戶卻感覺它存在。
用於實現虛擬的技術稱爲虛擬技術,在操作系統中利用了兩種方式實現虛擬技術:時分複用技術和空分複用技術。

時分複用技術

時分複用技術概念:將資源在不同的時間片內分配給各進程以使該資源被重複利用,從而提高資源的利用率。如採用時分複用的虛擬處理機,能夠在不同的時間片內處理多個用戶的請求,從而使得用戶感覺自己獨佔主機,而處理機在這期間也被充分的利用。

  1. 虛擬處理機技術:一臺處理機,通過時分複用的方法,能實現同時(宏觀上)爲多個用戶服務,亦即,利用多道程序設計技術,可將一臺物理上的處理機虛擬爲多臺邏輯上的處理機 ---- 虛擬處理機。
  2. 虛擬設備技術:通過時分複用的方法,將一臺物理I/O設備虛擬爲多臺邏輯上的I/O設備,並允許每個用戶佔用一臺邏輯上的I/O設備。
  • 這樣可使原來僅允許在一段時間內由一個用戶訪問的設備(即臨界資源),變爲允許多個用戶「同時」訪問的共享設備

  • 當一種資源在時間上覆用時,不同的程序或用戶輪流使用它。時分複用技術通過利用處理及的空閒時間運行其他程序,提高了處理機的利用率

空用複用技術

  • 實質上就是每次只把用戶程序的一部分調入內存運行,運行完成後將該部分換出,再換入另一部分到內存中執行,通過這樣的置換功能,實現了用戶程序的各個部分分時地進入內存運行。

  • 讓同一個頻段在不同的空間內得到重複利用。空分複用技術利用存儲器的空閒空間分區域分存放和運行其他多道程序,以此來提高內存的利用率。

注意:採用分時複用技術,每臺虛擬設備的平均速度必然等於或低於物理設備速度的1/N,同理,採用空分複用技術,一臺虛擬設備平均佔用的空間必然等於或低於物理設備所擁有空間的1/N

異步

  • 由於資源等因素的限制,使進程的執行通常都不可能「一氣呵成」,而是以「走走停停」的方式運行。

    對於內存中的每個進程,在何時能獲得處理機執行,何時又因提出某種資源請求而暫停,以及進程以怎樣的速度向前推進,每道程序總共需要多少時間才能完成等等,都是不可預知的

    進程是以人們不可預知的速度向前推進的,此即進程的異步性

操作系統的主要功能

image-20201022162226039

處理機管理功能

操作系統關於進程方面管理任務有如下幾種:進程控制進程同步進程通信調度

進程控制

  • 爲作業創建進程、撤銷(終止)已結束的進程,控制進程在運行過程中的狀態轉換。

進程同步

  • 爲了使多進程同時運行時協調,有兩種方式
    • 進程互斥方式:進程在對臨界資源進行訪問時,應採用互斥方式。(臨界資源加鎖實現,關鎖時禁止訪問;鎖開時允許訪問。
    • 進程同步方式:相互合作去完成共同任務的進程間,由同步機構對他們的執行次序加以協調。(信號量機制

進程通信

  • 實現相互合作進程之間的信息交換。

調度

  1. 作業調度:從後備隊列中按照一定算法選擇出若干個作業,爲他們分配運行所需資源,講作業調入內存後,分別建立與之對應的進程,使它們成爲可能獲得處理機的就緒進程,並將他們插入就緒隊列中。
  2. 進程調度:從進程就緒隊列中按照一定算法選出一個進程,將處理機分配給他,併爲他設置運行現場,使其投入執行。

存儲器管理功能

內存管理主要功能:內存分配內存保護地址映射內存擴充

內存分配

  1. 作用:爲每道程序分配內存空間;提高存儲器利用率,儘量減少內存空間碎片。
  2. 兩種內存分配方式
    1. 動態內存分配:每個作業所要求的基本內存空間也是在裝入時確定的,但允許作業在運行過程中繼續申請新的附加內存空間,以適應程序和數據的動態增長,也允許作業在內存中「移動」。
    2. 靜態內存分配:每個作業的內存空間是在作業裝入時確定的;在作業裝入後的整個運行期間,不允許該作業再申請新的內存空間,也不允許作業在內存中「移動」。
  3. 內存分配機制應具有的結構和功能:內存分配數據結構、內存分配功能、內存回收功能。

內存保護

  1. 主要作用:確保每道用戶程序都只在自己的內存空間內運行,彼此互不干擾;絕不允許用戶程序訪問操作系統的程序和數據;也不允許用戶程序轉移到非共享的其它用戶程序中去執行。
  2. 內存保護機制:設置兩個界限寄存器,分別用於存放正在執行程序的上界和下界。系統對每條指令所要訪問的地址進行檢查,如果發生越界,產生越界中斷請求,停止該程序的執行。

地址映射

  • 程序的邏輯地址通常從0開始,而物理地址不從0開始,因此需要一個映射轉換過程。主要功能即爲:將地址空間的邏輯地址轉換爲內存空間與之對應的物理地址。

內存擴充

  1. 藉助於虛擬存儲技術,從邏輯上去擴充內存容量。
  2. 爲了能在邏輯上擴充內存,系統必須具有內存擴充機制,用於實現下述各功能:
    1. 請求調入功能:允許在裝入一部分用戶程序和數據的情況下,便能啓動該程序運行。在程序運行過程中,若發現要繼續運行時所需的程序和數據尚未裝入內存,可向 OS 發出請求,由 OS 從磁盤中將所需部分調入內存,以便繼續運行。
    2. 置換功能:若發現在內存中已無足夠的空間來裝入需要調入的程序和數據時,系統應能將內存中的一部分暫時不用的程序和數據調至盤上,以騰出內存空間,然後再將所需調入的部分裝入內存。

設備管理功能

  • 主要任務
    • 完成用戶進程提出的I/O請求;爲用戶進程分配其所需的I/O設備;
    • 提高CPU和I/O設備的利用率;提高I/O速度;方便用戶使用I/O設備。
  • 爲此,設備管理應具有緩衝管理設備分配設備處理等功能。

緩衝管理

  • CPU運行的高速性和I/O低速性間的矛盾自計算機誕生時起便已存在。
    如果在I/O設備和CPU之間引入緩衝,則可有效地緩和CPU和I/O設備速度不匹配的矛盾,提高CPU的利用率,進而提高系統吞吐量。
    因此,在現代計算機系統中, 都毫無例外地在內存中設置了緩衝區,而且還可通過增加緩衝區容量的方法,來改善系統的性能

設備分配

  • 設備分配的基本任務,是根據用戶進程的I/O請求、系統的現有資源情況以及按照某種設備分配策略,爲之分配其所需的設備。如果在I/O設備和CPU之間,還存在着設備控制器和I/O通道時,還須爲分配出去的設備分配相應的控制器和通道。

設備處理

  • 設備處理程序又稱爲設備驅動程序。基本任務是用於實現CPU和設備控制器之間的通信,即由CPU向設備控制器發出I/O命令,要求它完成指定的I/O操作;反之,由CPU接收從控制器發來的中斷請求,並給予迅速的響應和相應的處理。
  • 處理過程是:設備處理程序首先檢查I/O請求的合法性,瞭解設備狀態是否是空閒的,瞭解有關的傳遞參數及設置設備的工作方式。然後向設備控制器發出I/O命令,啓動I/O設備去完成指定的I/O操作。

文件管理功能

  • 文件管理的主要任務是對用戶文件和系統文件進行管理以方便用戶使用並保證文件的安全性。
    爲此,文件管理應具有對文件存儲空間的管理目錄管理文件的讀/寫管理以及文件的共享與保護等功能。

文件存儲空間的管理

  • 由文件系統對諸多文件及文件的存儲空間,實施統一的管理。其主要任務是爲每個文件分配必要的外存空間,提高外存的利用率,進而提高文件系統的存、取速度。
  • 爲此,系統中應設置用於記錄文件存儲空間使用情況的數據結構,以供分配存儲空間時參考,還應具備對存儲空間進行分配和回收的功能

目錄管理

  • 目錄管理的主要任務,是爲每個文件建立一個目錄項,並對衆多的目錄項加以有效的組織,以實現方便的按名存取。
  • 通常由系統爲每個文件建立一個目錄項。目錄項包括文件名、文件屬性、文件在磁盤上的物理位置等。由若干個目錄項又可構成一個目錄文件。即用戶只須提供文件名, 即可對該文件進行存取。

文件的讀/寫管理

  • 該功能是根據用戶的請求,從外存中讀取數據;或將數據寫入外存。由於讀和寫操作不會同時進行,故可合用一個讀/寫指針。

文件的共享與保護

  • 防止未經覈準的用戶存取文件;防止冒名頂替存取文件;防止以不正確的方式使用文件。

操作系統與用戶之間的接口

  • 引題:image-20200913171719035

  • 包含關係:image-20200913172420937

用戶接口

  • 爲了方便用戶直接/間接控制自己的作業,操作系統提供了命令接口,該接口又分爲聯機用戶接口脫機用戶接口圖形用戶接口3種
聯機用戶接口
  • **用戶說一句,系統做一句。**用戶可通過先後鍵入不同命令的方式,來實現對作業的控制,直至作業完成。
  • image-20200913170246761
脫機用戶接口
  • **用戶說一堆,系統做一堆。**該接口是爲批處理image-20200913170618948
圖形用戶接口
  • 採用圖形化操作界面。

程序接口

  • 由一組系統調用命令(簡稱系統調用,也稱廣義指令)組成。
  • 系統調用的目的:請求系統服務
  • 系統調用/程序接口/程序接口 是操作系統提供給編程人員的接口 選Cimage-20200913175632848
  • 系統調用≠庫函數 選Aimage-20200913175227658

注意事項:

image-20200913171920463

操作系統的結構

傳統OS結構

無結構OS

  • OS的各部分是以最基本的過程存在,每個過程都可隨意地調用其他過程

模塊化結構OS

基本概念
  • 對OS的各部分經過了劃分,行程若干個具有一定獨立性和大小的模塊

image-20200914164420048

模塊獨立性
  • 模塊劃分過小→降低本身複雜性,但會引起模塊之間聯繫過多,造成系統混亂
  • 模塊劃分過大→增加模塊內部複雜性,使內部聯繫增加
  • 內聚性:指模塊內部各部分間聯繫的親密程度。內聚性高→模塊獨立性強
  • 耦合度:指模塊間相互聯繫和相互影響的程度。耦合度低→模塊獨立性強。
模塊接口法的優缺點
  • 優點
    • 提高OS設計的正確性、可理解性和可維護性
    • 增強OS的可適應性
    • 加速OS的開發過程
  • 不足/存在的問題
    • 接口規定困難
    • 存在無序性

分層式結構OS

分層式結構概念
  • 目標系統An和裸機系統A0之間有許多層次軟件:A1,A2,A3…An-1,使An通過這幾層最終能在A0上運行。

image-20200914170157431

分層結構的優缺點
  • 優點
    • 易保證系統的正確性:自下而上的設計方式使所有設計的決定都是有序的或者說是建立在較爲可靠的基礎上的,這樣比較容易保證整個系統的正確性。
    • 具有易擴充和易維護性:在系統中增加、修改或替換一個層次中模塊或整個層次時,只要不改變相應層次間接口,就不會影響其他層次,這就使得維護和擴充變得easy。
  • 缺點
    • 系統效率降低:由於層次結構是分層單項依賴的,必須在每層間都建立層次間的通信機制,OS執行一個功能就得由上到下穿越多層次,就會增加系統通信開銷,從而導致系統效率降低。

客戶端/服務端

客戶/服務器模式由來、組成和類型

  • 客戶機:每臺客戶機都是一個自主計算機,具有一定處理能力,客戶進程在其上運行,平時處理一些本地業務,也可以發送一個消息給服務器用以請求某項服務
  • 服務器:通常是一臺規模較大的機器,含有網絡文件系統或數據庫系統,應能爲網上所有用戶提供一種或多種服務。
  • 網絡系統:用於連接所有客戶機和服務器,實現他們之間通信和網絡資源共享的系統

客戶/服務器之間交互

一次完整的交互過程可以分成以下四步:

  1. 客戶發送請求消息
  2. 服務器接收消息
  3. 服務器回送信息
  4. 客戶機接收消息

客戶/服務器模式優點

  1. 數據的分佈處理和存儲
  2. 便於集中管理
  3. 靈活性和可擴充性
  4. 便於改編應用軟件

ps:經常會問到 在微內核OS中,爲什麼要採用客戶/服務器模式?我們答客戶/服務器模式的優點即可

微內核

微內核OS的基本概念

微內核技術——把操作系統中更多的成分和功能放到更高的層次(用戶模式)中去運行,而留下一個儘量小的內核,用它來完成操作系統最基本的核心功能。

  1. 足夠小的內核:微內核≠一個完整的OS,含有:
    1. 與硬件處理緊密相關的部分
    2. 一些較基本的功能
    3. 客戶和服務器之間的通信
  2. 基於【客戶/服務器模式】image-20200914173409746
  3. 應用"機制和策略分離"原理
    1. 機制:是指在實現某一功能時的具體規定或說原則
    2. 策略:在機制的基礎上,藉助某些參數和算法,用以實現該功能的優化,或達到不同的目標
  4. 採用面向對象技術

微內核的基本功能

基於【機制與策略分離】的原理,將機制部分以及與硬件緊密相關的部分放入微內核中。由此微內核通常具有如下幾個方面功能:

  1. 進程(線程)管理
  2. 低級存儲器管理
  3. 中斷和陷入處理

微內核操作系統的優點

  1. 提高了系統的可擴展性
  2. 增強了系統的可靠性
  3. 可移植性強
  4. 提供了對分佈式系統的支持
  5. 新技術——融入了面向對象技術

微內核操作系統存在的問題

  1. 缺點:微內核操作系統的運行效率相較早期操作系統有所降低
  2. 改進方法:可以把一些常用的操作系統基本功能由服務器移入微內核中

進程和線程

前趨圖和程序執行

前趨圖

  • 前趨圖(Precedence Graph)是指一個有向無循環圖,可記爲DAG,用於描述進程之間執行的先後順序

程序執行

程序順序執行

  • 特徵:
    • 順序性:所謂順序性是指,處理機嚴格的按照程序所規定的順序執行,一個操作的開始必須在其前一個操作結束之後。
    • 封閉性:所謂封閉性是指,程序在執行的時候獨佔全機的資源
    • 可再現性:所謂可再現性是指,只要初始條件運行環境系統相同,其運行結果一定是一樣的。

程序併發執行

  • 事實上,只有不存在前趨關係的程序之間纔有可能併發執行,否則無法併發執行

  • 特徵:

    • 間斷性:所謂間斷性指的是,由於多個程序對資源的要求產生的制約性,而導致的某一個程序在運行時等待資源的情況。 比如有兩個程序都需要使用打印機這個資源,如果其中的一個程序已經佔用,而另一個必須等待。這樣後者表現出來的就是程序運行時的間斷性。
    • 失去封閉性:所謂失去封閉性指的是,由於多個程序併發執行會共享資源,從而導致各個程序運行環境會失去封閉性。
    • 不可再現性:所謂不可再現性是指相同的輸入,由於資源的共享,導致最後的輸出結果不同。

進程的描述

image-20201022161832422

進程的定義和特徵

定義

  • 程序:是靜態的,是一個存放在磁盤裏的可執行文件,是一系列的指令集合

  • 進程:是動態的,是進程實體的運行過程,是系統進行資源分配和調度的一個獨立單位。

    其中,進程實體包含三部分:程序段相關的數據段PCB

  • 程序進程關係:一個程序多次執行會對應多個進程,比如說QQ可以登錄三個賬號。那麼既然都是QQ,那OS是怎麼區分不同進程的呢?當進程被創建的時候,OS會爲該進程分配一個唯一的,不重複身份證——PID(Process ID,進程ID)image-20200916193516137

  • 進程控制塊(PCB):OS需要記錄進程PID,分配了哪些資源,運行情況,那麼這些信息需要記錄到哪裏呢?答案就是進程控制塊——PCB。image-20200916192007658

    • 作用:PCB的作用是使一個在多道程序環境下不能獨立運行的程序(含數據)成爲一個能獨立運行的基本單位,一個能與其他進程併發執行的進程。下面是具體作用:
      • 作爲獨立運行基本單位的標誌:在進程的整個生命週期中,系統總是通過PCB對進程進行控制的,亦即系統是根據 進程的PCB感知該進程的存在的,所以,PCB是進程存在的唯一標誌。
      • 能實現間斷性運行方式
      • 提供進程管理所需要的信息
      • 提供進程調度所需要的信息
      • 實現與其他進程的同步與通信

特徵

  • 主要由:動態性,併發性,獨立性,異步性,結構性組成。

image-20200916193752881

進程的基本狀態及轉換

image-20201022161752742

進程的狀態

進程狀態有五種:創建狀態,就緒狀態,執行狀態,阻塞狀態,終止狀態;其中就緒、執行、阻塞是三種基本狀態。

創建態、就緒態

  • 創建狀態:對於處於創建態的進程,當其獲得了所需的資源以及對其PCB的初始化工作完成後,便可由創建態轉入就緒態
  • 就緒狀態:進程已經處於準備好運行的狀態了,只需要CPU臨門一腳便可以立即執行。

運行態

  • 運行態:指進程已經獲CPU,其程序正在執行的狀態。在單處理機系統中,只有一個進程處於執行狀態,而在多處理機系統中,有多個進程處於執行狀態。

image-20200916195133485

阻塞態

  • 阻塞態:指正在執行的進程由於發生某事件(I/O請求,申請緩衝區失敗等)暫時無法繼續執行時的狀態,亦即進程的執行收到阻塞。image-20200916203322409

終止態

  • 終止態:即一個進程達到了自然結束點,或是出現了無法克服的錯誤,或是被操作系統所終結,或是被其他有終止權的進程所終結,它將進入終止狀態。

    image-20200916204018353

進程的轉換

三態模型

  • 基本的三態模型:這裏寫圖片描述

五態模型

  • 未引入掛起的五態模型:

image-20200916204307618

引起進程狀態轉換的具體原因如下:

  • NULL→新建態:執行一個程序,創建一個子進程。

  • 新建態→就緒態:當操作系統完成了進程創建的必要操作,並且當前系統的性能和虛擬內存的容量均允許。

  • 就緒態→運行態:進程被調度

  • 運行態→終止態:當一個進程到達了自然結束點,或是出現了無法克服的錯誤,或是被操作系統所終結,或是被其他有終止權的進程所終結。

  • 運行態→就緒態:運行時間片到;出現有更高優先權進程。

  • 運行態→阻塞態:等待使用資源;如等待外設傳輸;等待人工干預。

  • 阻塞態→就緒態:申請資源被分配,或等待的事件已經發生了

  • 就緒態→終止態:未在狀態轉換圖中顯示,但某些操作系統允許父進程終結子進程。

  • 阻塞態→終止態:未在狀態轉換圖中顯示,但某些操作系統允許父進程終結子進程。

  • 終止態→NULL:完成善後操作。

七態模型

接下來,我們引入了兩個操作:掛起和激活

當掛起操作作用於某個進程時,該進程將被將被掛起,意味着此時該進程處於靜止狀態;

假如進程正在執行,他將暫停執行。

假如進程原本就處於就緒狀態,則該進程此時暫不接受調度。

與掛起操作對應的就是激活啦。

  • 引入掛起後的進程狀態轉換五態模型:

這裏寫圖片描述

  • 引入創建和終止——七態模型:

    image-20201005151351838

這裏寫圖片描述

引起進程狀態轉換的具體原因如下:

  • 等待態—→掛起等待態:如果當前不存在就緒進程,那麼至少有一個等待態進程將被對換出去成爲掛起等待態;操作系統根據當前資源狀況和性能要求,可以決定把等待態進程對換出去成爲掛起等待態。
  • 掛起等待態—→掛起就緒態:引起進程等待的事件發生之後,相應的掛起等待態進程將轉換爲掛起就緒態。
  • 掛起就緒態—→就緒態:當內存中沒有就緒態進程,或者掛起就緒態進程具有比就緒態進程更高的優先級,系統將把掛起就緒態進程轉換成就緒態。
  • 就緒態—→掛起就緒態:操作系統根據當前資源狀況和性能要求,也可以決定把就緒態進程對換出去成爲掛起就緒態。
  • 掛起等待態—→等待態:當一個進程等待一個事件時,原則上不需要把它調入內存。但是在下面一種情況下,這一狀態變化是可能的。當一個進程退出後,主存已經有了一大塊自由空間,而某個掛起等待態進程具有較高的優先級並且操作系統已經得知導致它阻塞的事件即將結束,此時便發生了這一狀態變化。
  • 運行態—→掛起就緒態:當一個具有較高優先級的掛起等待態進程的等待事件結束後,它需要搶佔 CPU,,而此時主存空間不夠,從而可能導致正在運行的進程轉化爲掛起就緒態。另外處於運行態的進程也可以自己掛起自己。
  • 新建態—→掛起就緒態:考慮到系統當前資源狀況和性能要求,可以決定新建的進程將被對換出去成爲掛起就緒態。

進程的組織

線性方式

  • 不論進程的狀態如何,將所有的PCB連續地存放在內存的系統區。這種方式適用於系統中進程數目不多的情況。

鏈接方式

  • 系統按照進程的狀態將進程的PCB組成隊列,從而形成就緒隊列、阻塞隊列、運行隊列等。image-20200919213505282

索引方式

  • 該方式是線性表方式的改進,系統按照進程的狀態分別建立就緒索引表、阻塞索引表等。image-20200919213530758

進程控制

進程控制的主要功能是對系統中的所有進程實施有效的管理,它具有創建新進程,撤銷已有進程,實現進程狀態轉換等功能;

簡單來說,進程控制→實現進程狀態轉換。

image-20201022161725493

  • 簡單的流程圖:

    image-20201005155458987

OS內核

image-20200919214807617

與硬件緊密相關的模塊、各種常用的設備的驅動程序以及運行頻率較高的模塊,安排在緊靠硬件的軟件層次中,將它們常駐內存,通常被稱爲OS內核也就是OS內核其實本質上是各個模塊

原語

  • 我們知道原語的執行具有原子性,它執行過程只能一氣呵成,不允許被打斷,那麼爲什麼要一氣呵成呢?下圖即爲解釋**,假如不一氣呵成,就會導致操作系統某些關鍵的數據結構信息不統一,就會影響操作系統進行別的管理工作**。image-20200919215018317
  • 如何實現原語的原子性呢?其實是利用了「關中斷指令"和」開中斷指令";
  • CPU執行了關中斷指令後,不會再check中斷信號,直到遇到了開中斷指令纔會再去check;
  • 因此關——開中斷之間的指令是連續的,不可中斷的,這就實現了原子性;image-20200919215955758

進程的創建

創建原語:

  1. 申請空白PCB
  2. 爲新進程分配所需的資源
  3. 初始化PCB
  4. 將PCB插入就緒隊列

哪裏會用到進程創建呢?

  1. 用戶登錄
  2. 作業調度
  3. 提供服務
  4. 應用請求

image-20200919220556546

進程的終止

終止/撤銷原語:

  1. 從PCB集合中找到終止進程的PCB
  2. 若該進程正在運行,立刻剝奪CPU,將CPU分配給其他進程
  3. 終止其所有子進程
  4. 將該進程所擁有的所有資源還給父進程或操作系統
  5. 刪除PCB

哪裏會用到進程終止呢?

  1. 正常結束:進程自己請求終止
  2. 異常結束:非法使用特權指令
  3. 外界干預:用戶自己選擇殺某進程

image-20200919222346641

進程的阻塞和喚醒

被什麼事件所阻塞就會被該事件所喚醒

image-20200919222900878

進程的切換

切換原語:

  1. 運行環境信息存入PCB
  2. PCB移入相應隊列
  3. 選擇另一個進程執行,並更新其PCB
  4. 根據PCB恢復進程所需的運行環境

這裏有一個地方:進程所需的運行環境是什麼東西呢?

image-20200920180827278

首先回顧一下我們程序是如何運行的:是通過把我們的代碼保存到硬盤然後轉入內存,然後CPU去從內存中讀取一條條指令,然後我們的程序就跑起來了。那麼CPU中有個東西 叫做寄存器。它們有不同的功能,比如可以存放下一條指令地址,也可以存放正在執行的指令,也可以保存暫時運算得到的結果;然而我們知道寄存器並不是很專一的,他有可能會隨時被其他的進程使用,那我們之前運算的結果啊,什麼保存的指令啊,豈不是都不見了嗎?這個時候就會用到我們的PCB了,它能夠保持關鍵的一些信息,也就是運行環境,這樣等我們的寄存器又空閒下來了的時候,我們就可以繼續我們未完成的指令啦。image-20200920181231409

進程同步

image-20201022160937233

進程同步與互斥

首先,我們回顧一下我們之前學的進程異步問題,由於併發執行的進程以各自獨立,不可預知速度向前推進,我們所得到的結果往往也會不一樣,而我們往往有時候需要控制一個事件的發生在一個事件前,那麼就需要進程同步

同步也稱爲直接制約關係,是指爲了完成某種任務而建立的兩個或多個進程,這些進程因爲需要在某些位置上協調他們的工作次序而產生的制約關係

image-20200924203323774

有進程同步就有進程互斥,那麼進程互斥又是什麼呢?

要明白互斥,就引入了一個概念:臨界資源

臨界資源,即一個時間段內只允許一個進程使用的資源。對於該資源我們必須互斥的訪問,也就是我訪問,你不能訪問,反之亦然;因此,進程互斥,即指當一個進程訪問某臨界資源時,另一個想訪問此臨界資源的進程必須要等待,只有當我正在訪問該資源的進程訪問結束了,釋放掉了,下一個進程才能去訪問該資源。

image-20200924203831680

那麼我們一般是如何進行對臨界資源的訪問的呢?image-20200924204737502

  • 進入區:負責檢查是否可以進入臨界區(上鎖)
  • 臨界區:訪問臨界資源的那段代碼
  • 退出區:用於將臨界區正被訪問的標誌恢復爲未被訪問的標誌
  • 剩餘區:做其他處理

ps:臨界區是進程中訪問臨界資源的代碼段;進入區和退出區是負責實現互斥的代碼段;臨界區也被稱爲」臨界段"

同步機制遵循的規則

  • 空閒讓進:多中選一
  • 忙則等待:互斥訪問
  • 有限等待:避免死等
  • 讓權等待:避免忙等

image-20200924205632915

硬件同步機制

讓硬件同步即爲進程互斥的硬件實現方法:中斷屏蔽方法,TestAndSet,Swap指令

image-20201022160746350

中斷屏蔽方法

  • 在進入鎖測試之前關閉中斷,直到完成鎖測試並上鎖之後才能打開中斷。

image-20200924211536165

TestAndSet

簡稱TS指令,也有稱TestAndSetLock指令,或TSL指令

用TS指令管理臨界區的時候,爲每個臨界資源設置一個布爾變量lock;

用lock的布爾值就可以判斷資源是否空閒,進程能否訪問。

  • 優點:實現簡單;適用於多處理機的環境
  • 缺點:不滿足讓權等待

image-20201005153906850

Swap指令

有的地方稱爲Exchange指令,或XCHG指令;Swap指令用硬件實現,不允許被中斷

Swap指令與TS指令在邏輯上其實差不多,但Swap需要兩個參數,不需要返回值,TS需要一個共享的變量實現互斥,因此在不同的地方就要用不同的方式去進行進程互斥。

image-20201005153942707

信號量

image-20201022160710930

信號量機制

image-20200927175523422

由於之前的措施方案無法實現進程的「讓權等待"問題,因此我們引出了信號量這個概念進行解決;

image-20200927220306063

整型信號量

  • Dijkstra把整型信號量定義爲一個用於表示資源數目的整形量S,它僅能通過P\V操作進行訪問。(P\V 即 wait & signal)這兩個操作是原子操作,是不可以在執行過程中被中斷的。
  • 整形信號量存在的問題:不滿足讓權等待原則

image-20200927221635070

記錄型信號量

  • 對於每次的wait操作,意味着進程請求一個單位的該類資源,使系統中可供分配的該類資源數減少一個,因此描述爲S→value–;S→value < 0時,表 示該類資源已分配完畢,因此進程應調用block原語進行自我阻塞,放棄處理機,並插入到信號量鏈表S→list中
  • 對於每次的signal操作,意味着執行進程釋放一個單位資源,使系統中可供分配的該類資源數增加一個,故S→value++操作表示資源數目+1。若+1後還是S→value <= 0,表示在該信號量鏈表中仍有等待該資源的進程被阻塞了,故應該調用wakeup原語,將S→list鏈表中的第一個等待進程喚醒。(被喚醒進程從阻塞態→就緒態)

image-20201005154049852

ps:記錄型信號量可實現進程互斥、進程同步;如果出現了P(S),V(S)的操作,除非默認說明,默認S爲記錄型信號量

信號量應用

image-20201022160633374

實現進程互斥

image-20200928152442455

  • 爲使得多個進程互斥訪問某臨界資源【目的】,爲該資源設置 互斥信號量【mutex】,初始值爲1
  • 將該資源置於P、V操作之間;
  • 注意:利用信號量機制去實現進程互斥時必須保證我們的P\V操作是成對出現的
    • 缺少P會導致系統混亂,不能保證對臨界資源互斥訪問
    • 缺少V將會使臨界資源永遠不被釋放,導致臨界資源永遠不被釋放,從而使因等待該資源的阻塞的進程不能被喚醒
實現進程同步
  • 進程同步:要讓各併發進程按要求有序地推進

image-20200928160518569

現在P1,P2併發執行,由於存在異步性,二者交替推進次序無法控制,是不確定的;

假如我P2的代碼4需要用到P1的代碼1、2、3運行結果才能執行的話,我就得保證代碼4是在代碼3後執行;

此即進程同步問題:讓本異步併發的進程互相配合,有序推進。

重點:在前操作之後執行V(S),在後操作之前執行P(S); image-20200928200922651

實現前趨關係

每一對的前趨關係都是一個進程同步的問題(爲了保證一前一後的操作)

爲了實現這個目標,我們需要做的事情

  1. 爲每一對前趨關係各設置一個同步信號量
  2. 在【前操作】的之後相對應的同步信號量執行V
  3. 在【後操作】的之前相對應的同步信號量執行P

image-20200928201842866

管程

image-20201022160532798

引子

  • 爲什麼要引入管程?因爲信號量機制存在一定的問題:編寫程序困難,容易出錯(廢話,這麼多PV操作,想不錯都難)因此我們在1973年引入管程機制進行處理;

管程的定義

代表資源的數據結構以及由對該共享數據結構實施操作的一組過程所造成的資源管理程序共同構成了一個操作系統的資源管理模塊——管程

管程是一種特殊的軟件模塊,由以下部分組成:

  1. 局部於管程的共享數據結構說明;
  2. 對該數據結構進行操作的一組過程(就是函數)
  3. 對局部於管程的共享數據設置初始值的語句【對數據結構初始化的語句】
  4. 管程有一個名字

發現了嗎,管程和我們面向對象的有點相似——可以定義一些數據,可以定義一些對這些數據操作的函數,對屬性初始化的語句。

管程的基本特徵

  1. 局部於管程的數據只能被局部於管程的過程所訪問
  2. 一個進程只有通過調用管程內的過程才能進入管程訪問共享數據
  3. 每次僅允許一個進程在管程內執行某個內部過程

什麼意思呢?通過1+2我們可以知道,假如我們要修改管程內的數據結構,我們只能夠通過調用管程內封裝好的方法(函數)去修改數據結構;而3則實現了進程互斥

管程中的條件變量

我們使用管程實現進程同步需要用到同步工具,如wait,signal;

但僅僅有這兩個是不夠的,我們知道,每次僅能有一個進程進入管程,假如某進程在管程中被掛起或阻塞就得等很久了,那麼解決這問題就引入了——條件變量 condition

怎麼用呢?管程中對每個條件變量以說明**:condition x,y**;條件變量的操作是wait,signal;

每個條件變量保存一個鏈表,用以記錄因爲這條件變量所阻塞的所有進程,提供2個操作:

x.wait 和 x.signal

  • x.wait:正在調用管程的進程因爲x條件需要被阻塞或者掛起,調用x.wait將自己插入到x條件的等待隊列上,並釋放管程,直到x條件變化。此時其他進程可以使用該管程——讓出了入口。
  • x.signal:若正在調用管程的進程發現x條件發生了變化,則調用x.signal重新啓動一個因x條件而阻塞或掛起的進程,如果存在多個這樣的進程,則選擇一個,如果沒有,則繼續執行原進程,而不產生任何結果。
    • 注意了 這與信號量機制的signal操作不能混爲一談,信號量中的signal需要s++操作,信號量改變了。

管程解決生產者消費者問題

image-20201001155941689

  1. 假如兩個生產者進程併發執行,依次調用insert過程的話:
    1. 第一個生產者進程可以順利執行完insert函數
    2. 假如在第一個生產者進程還未結束的時候,第二個生產者進程插入進來了,就會把第二個進程阻塞在insert函數後面,排隊
  2. 假如兩個消費者進程先執行,生產者進程後執行的話:
    1. 第一個進程進來,發現count = 0,那麼就執行wait操作,就等待在empty變量相關的隊列中
    2. 同樣的,第二個就排在了empty變量相關的隊列中
    3. 此時假如有個生產者進程進來了,進行生產,把生產品放在了緩衝區當中,假如發現自己的產品是第一個產品,那麼此時有可能有別的消費者進程在等待產品,就執行一個喚醒操作,喚醒一個消費者進程。
    4. 然後count–,檢查拿走前緩衝區是否是滿的,假如是滿的,說明有生產者進程需要被喚醒,就來一個signal(full)操作。

Java中類似管程的機制

Java中,如果用關鍵字【synchronized】描述一個函數,那麼這個函數同一個時間段只能被一個線程調用。

image-20201001164432414

經典的進程同步問題

生產者-消費者問題

問題描述

image-20201005154151145

問題分析
  • 緩衝區未空(有產品)V→P消費者消費
  • 緩衝區未滿P→V生產者生產

image-20200928204830509

問題的解法步驟
  1. 關係分析,找出題目中描述的各個進程,分析他們之間的同步、互斥關係
  2. 根據各進程的操作流程去確定P、V的大致順序
  3. 設置信號量,根據題目條件設信號量初值
    1. 互斥信號量初值一般爲1
    2. 同步信號量的初值看對應的資源初值值(0/n…)
具體實現
  1. 設置好信號量
    1. 互斥信號量 = 1:實現對緩衝區的互斥訪問
    2. 同步信號量empty = n:實現空閒緩衝區的數量
    3. 同步信號量full = 0:代表產品的數量,也即非空緩衝區的數量
  2. 分別在生產者,消費者中放置P、V操作(注意順序,以及操作的哪個信號量)

image-20200928205550396

思考
  • 想一想 能不能改變相鄰P、V操作的順序呢?

image-20201005154232845

得出結論了:實現互斥的P操作必須放在實現同步的P操作之後;由於V操作並不會導致進程阻塞,因此兩個V操作順序可以交換

多生產者-多消費者問題

問題描述

image-20200929094120224

注意 這裏的多生產者的多 代表的不是數量 而是多個類型

問題分析
  • 找出題目描述的各進程,分析它們之間同步、互斥關係;
    • 互斥關係:對緩衝區(盤子)的訪問要互斥的進行
    • 同步關係:父親放蘋果,女兒才能取蘋果;母親放橘子,兒子才能取橘子;盤子爲空時,父/母才能放水果,因此需要兒/女進行從盤子取水果;
  • 根據進程的操作流程確定P、V操作大致順序
    • 實現互斥:在臨界區前後分別P、V
    • 實現同步:前操作後V,後操作前P
  • 設置信號量
具體實現
  • 實現互斥訪問盤子:mutex = 1
  • 多少個蘋果 apple = 0
  • 多少個橘子 orange = 0
  • 盤子中還能放多少水果 plate = 1

image-20200929095442030

以父親和女兒舉例:

父親首先應該P盤子,查看是否爲空,如果爲空,則V蘋果(蘋果++);女兒首先P蘋果,查看是否準備好了,有的話就取出,V盤子(盤子++);爲了保證互斥,必須在P、V操作之中加入對互斥信號量mutex 的 P、V操作。

思考

可不可以不要互斥信號量mutex?

image-20201005153712342

由於緩衝區大小爲1,因此orange,apple,plate三者中最多隻有一個是1;這樣的話最多隻有一個進程的P操作不會被阻塞,可以順利進入臨界區,因此可以順利執行;

那麼假如緩衝區(plate)數量爲2呢?

那麼父親和母親都能訪問盤子,有可能出現不同進程寫入緩衝區的數據相互覆蓋的問題;

得出結論:如果緩衝區的大小大於1,那麼就必須專門設置一個互斥信號量mutex來保證互斥的訪問緩衝區

吸菸者問題

問題描述

image-20200929104120937

問題分析
  • 找出題目描述的各進程,分析它們之間同步、互斥關係;
    • 同步關係:桌上有組合1→第一個抽菸者取走;組合2→第二個抽菸者取走;組合3→第三個抽菸者取走
    • 互斥關係:桌子只有一個,可以理解爲容量爲1的緩衝區需要互斥訪問
  • 根據進程的操作流程確定P、V操作大致順序
  • 設置信號量

image-20200929104936547

具體實現
  • 桌上組合1、2、3分別爲 offer1 offer2 offer3,他們的初值都是0
  • 設置一個信號量i,用於實現三個抽菸者輪流吸菸

image-20201010163817853

以smoker1爲例,首先P(offer1)檢查是否有需要的組合1,有的話就拿走去抽,並且告訴供給者抽完了,然後供給者i++,p一下finish,並將下一個組合放在桌上然後v下一個組合;

讀者-寫者問題

問題描述

image-20201010165136258

問題分析
  • 找出題目描述的各進程,分析它們之間同步、互斥關係;
    • 互斥關係寫進程-寫進程 寫進程-讀進程 這兩者存在互斥關係。而讀進程-讀進程不存在互斥
  • 根據進程的操作流程確定P、V操作大致順序
  • 設置信號量
    • 一個互斥信號量RW:寫者訪問文件的前後執行PV,讀者訪問前後執行PV
    • 整型變量count 記錄當前有幾個讀進程在訪問文件
    • 一個互斥信號量 mutex :保證對count變量的互斥訪問
    • 一個互斥信號量 w :用於實現寫優先

image-20201010165807840

具體實現

image-20201010171424288

哲學家進餐問題

問題描述

image-20201010171711073

問題分析
  • 找出題目描述的各進程,分析它們之間同步、互斥關係;
    • 互斥關係:五位哲學家與左右鄰居對其中間筷子的訪問是互斥的
  • 根據進程的操作流程確定P、V操作大致順序
  • 設置信號量
    • 一個互斥信號量組chopstick[5]:用於實現對五個筷子的互斥訪問。其中哲學家編號**[0…4],各哲學家i的左邊筷子編號爲i**,右邊筷子編號爲**(i+1)%5**

然而我們發現 這樣子會導致死鎖的現象

image-20201010172704302

具體分析

按照之前的方法會發生死鎖現象,那我們怎麼解決呢?

有三種方法:

  1. 最多允許四個哲學家同時進餐,這樣可以保證至少有一個哲學家是可以拿到左右兩隻筷子的
  2. 要求奇數號哲學家先拿左邊的筷子,然後再拿右邊的筷子;偶數號哲學家相反。這種方法可以保證如果相鄰的兩個奇偶號哲學家都想吃飯的話,只有有其中一個可以拿起第一隻筷子,而另一個因爲拿不到第一個筷子就直接阻塞了。
  3. 僅當一個哲學家左右兩隻筷子都可用時才允許他抓筷子【這也是後面的破壞請求和保持條件 方法】

下面以第三種方法爲例,進行解決

image-20201010174404648

進程通信

image-20201022161648794

進程通信概念

  • 進程通信是指進程之間的信息交換。
  • 進程所擁有的內存地址空間相互獨立,換而言之,進程不能直接訪問另一個進程的地址空間,然而有時候有需要信息交換,那該怎麼辦呢?OS提供了一些方法給我們。

image-20201001165400139

共享存儲

前提:兩個進程對於共享空間的訪問必須是互斥的。

  • 基於數據結構共享:各進程公用某些數據結構,實現各進程的信息交換:如生產者-消費者問題中的有界緩衝區。是低級通信方式。
  • 基於存儲區共享:在內存中畫一片共享存儲區,數據形式和存放位置由進程控制而非OS。是高級通信方式。

image-20201001165948214

管道通信

  • 【管道 pipe文件】是指用於連接讀寫進程的一個共享文件,本質是內存空間中開闢的一個固定大小的緩衝區
  • 管道採取半雙工通信,一個時間段內只能實現單向傳輸;
  • 進程互斥訪問管道
  • 管道寫滿時,寫進程的系統調用被阻塞;管道爲空時,讀進程的系統調用被阻塞
  • 沒寫滿不準讀,沒讀空不準寫。
  • 管道數據被讀出後被拋棄,意味着讀進程最多隻能有一個,不然可能會讀錯數據。

image-20201005154325305

消息傳遞

進程通過【格式化的消息】爲單位,將通信的數據封裝在消息中,通過OS提供的發送接收原語,在進程間進行消息傳遞,完成進程的數據交換。是一種高級通信方式。

  • 直接通信方式:發送進程利用OS提供的發送原語直接把消息發給接收進程/消息直接掛到接收方的消息隊列中。

  • 間接通信方式/信箱通信方式:發送進程先發送到中間實體(信箱)中,接受進程再去接收,完成進程間的通信。

    image-20201005154353653

線程

image-20201022161600061

線程的概念和特點

  • 什麼是線程?爲什麼要引入線程?

下列是三個進程,他們所佔用不同的空間內存和系統資源;假如我們要切換進程的時候,需要用保存/恢復運行環境,還需要切換內存地址空間(更新快表、更新緩存)開銷非常大,因此,人們引入了線程機制

image-20201001175345544

  • 引入了線程之後,線程是CPU調度基本單位。一個進程裏面可以包含多個線程。線程之間可以併發進行。
  • 但是進程依舊是資源分配基本單位,從屬一進程的各線程共享使用進程的資源。
  • 同一個進程內各個進程間併發,不需要切換進程運行環境和內存地址空間,省時省力。

image-20201001180053003

引入線程後的變化

image-20201005154628052

線程的屬性

image-20201005154719829

線程的特性與優點

  • 進程間併發,開銷很大;線程間併發,開銷很小

  • 引入線程機制之後,併發帶來的系統開銷降低,系統併發性提升

ps:從屬於不同進程的線程間切換,也會導致進程間切換,開銷也會很大。

  • 從屬於同一進程的各個線程共享進程所擁有的資源。
  • 進程間通信必須請求操作系統服務(CPU需要切換到核心態),開銷大;同進程下線程通信,無需OS干預,開銷更小;

image-20201001193612876

線程實現方式

用戶級線程

image-20201003164146178

  1. 線程的管理工作是由誰完成的?
    1. 答 線程的管理工作由應用程序通過線程庫來完成的,不是通過OS完成的
  2. 線程切換是否需要CPU從用戶態轉換爲內核態?
    1. 答 在用戶態下,由應用程序通過線程庫就可以進行線程切換了
  3. OS是否能意識到用戶及線程的存在?
    1. 答 意識不到,只有用戶能意識到有多個線程
  4. 用戶級線程有什麼優點和缺點?
    1. 答 優點:用戶級線程的切換在用戶態可以完成,不需要切換到核心態,系統開銷小,效率高
    2. 缺點:假如其中某一個線程被阻塞了,其他線程都會被阻塞,併發度不高;

內核級線程

image-20201003165327004

  1. 線程的管理工作由誰來完成?
    1. 答 由OS內核完成
  2. 線程切換是否需要CPU從用戶態轉換到內核態?
    1. 答 由於線程調度、切換工作由內核負責,因此在內核級線程的線程切換時需要從用戶態轉換到內核態的。
  3. OS能否意識到內核級線程的存在?
    1. 答 OS會爲每個內核級線程建立對應TCB,然後通過TCB對線程進行管理,因此,OS能夠意識到內核級線程的存在
  4. 內核級線程的實現方式的優缺點?
    1. 答 優點:內核級線程是處理機調度的基本單位,而進程只作爲資源分配的基本單位;因此在多核CPU中,這幾個線程可以被分配在多個不同cpu中併發執行,其中一個線程被阻塞了,其他的也能正常執行;
    2. 缺點:一個用戶進程會佔用多個內核級線程,線程切換由OS內核完成,由於用戶態到核心態的轉換需要開銷,因此線程管理成本高,開銷大。

多線程模型

  • 一對一模型

image-20201003170653283

  • 多對一模型

image-20201003170837716

  • 多對多模型

image-20201003171220652

處理機調度與死鎖

處理機調度

image-20201022161521827

調度基本概念

  • 當有一堆任務需要處理,但由於資源有限,這些事情沒法同時處理。這就需要確定某種規則來決定處理這些任務的順序,這就是調度所研究的問題,簡單來說就算:按照某種算法選擇一個進程將處理機分配給他

image-20201005143651479

處理機調度的層次

高級調度

image-20201005154801232

  • 高級調度/長程調度/作業調度,調度對象爲作業;

  • 高級調度主要用於多道批處理系統中,什麼是多道批系統呢?雖然前面講過了 再複習一遍吧:

    image-20201005144635558

  • 高級調度根據某種算法/一定的原則從處於後備隊列的作業中挑選一個/多個作業,分配內存等資源,建立PCB,使他們獲得競爭處理機的權利

  • 高級調度是外存與內存之間的調度,每個作業只調入一次,調出一次。調入時創建相應PCB,作業調出時又撤銷PCB。由於調出的時機一定是作業運行結束的時候,因此高級調度主要是解決調入的問題

中級調度

image-20201005154819601

  • 中級調度/內存調度,引入這個調度的目的是爲了提高內存的利用率和系統的吞吐量

  • 引入虛擬存儲技術後,將那些暫時不能運行的進程調至外存等待,此時進程的狀態稱爲:就緒駐外存狀態(掛起狀態),等它們已具備運行條件且內存又稍有空閒時,由中級調度決定,重新調入內存並修改狀態爲就緒狀態,掛在就緒隊列上等待

    ps:PCB並不會一起被調到外存,而是常駐內存。OS通過內存中的PCB保持對各進程的監控和管理

低級調度

image-20201005151550183

  • 低級調度/進程調度/短程調度:調度對象是進程(或內核級線程);
  • 主要功能是根據某種算法/方法/策略,決定就緒隊列中哪個進程應該獲得處理機,將處理機分配給它。
  • 這種調度方式是OS中最基本的一種調度,在多道批、實時和分時三種類型OS中必須配置這級調度;
  • 低級調度的頻率很高,一般幾十毫秒一次;

三種調度方式的聯繫、對比

image-20201005152354921image-20201005152256817

進程調度

進程調度的時機

image-20201005160523382

  • 這個地方有人會說:那麼進程處於臨界區時,不能進行處理機調度咯? 這個說法是錯的 爲什麼呢?

    • 臨界資源:一個時間段內只允許一個進程使用的資源,各進程需要互斥地訪問臨界資源。
    • 臨界區:訪問臨界資源的那段代碼
    • 內核程序臨界區:一般是用來訪問某種內核數據結構的(比如進程的就緒隊列,由各就緒隊列PCB租成)

    image-20201005160815845

進程調度的方式

非剝奪調度方式

image-20201005161431904

在採用這種方式時,可能引起進程調度的因素歸結爲:

  1. 正在執行的進程運行完畢,或因發生某事件而使其無法再繼續執行;
  2. 正在執行中的進程因提出I/O請求而暫停執行;
  3. 在進程通信/同步過程中,執行某原語操作;
剝奪調度方式

image-20201005161437212

搶佔並非是任意的,必須遵循一定原則。包括:

  1. **優先權原則:**指允許優先級高的新進程搶佔當前進程的處理機;
  2. **短進程優先原則:**指允許新的短進程可以搶佔當前長進程的處理機;
  3. **時間片原則:**即各進程按時間片輪轉運行時,當正在執行的進程一個時間片用完時,便停止該進程的執行而重新進行調度;

進程調度的切換與過程

image-20201005162732619

調度算法

調度算法的評價指標

image-20201022161204191

CPU利用率

image-20201005163718195

系統吞吐量

image-20201005163838042

週轉時間

image-20201005164349602

  • 對於每個用戶而言,都希望自己作業的週轉時間短一點,然而對於OS,則向作業週轉時間平均值小;那麼引入了概念:帶權週轉時間,平均帶權週轉時間;

    image-20201005164734068

等待時間

image-20201005165031694

響應時間

image-20201005165627506

調度算法種類

image-20201022161053467

image-20201022161135651

FCFS-先來先服務算法

  • FCFS例題:

    image-20201007173555912

SJF-短作業優先算法

image-20201007174950265

  • SJF例題:

    • 非搶佔式:

      在0時刻,只有P1進來了,在他運行的時間7內,P2,P3,P4都進來了,在P1結束後選擇運行時間最短的P3執行,後續同理;

      image-20201007174045837

    • 搶佔式:

      image-20201007174549414

HRRN-高相應比優先算法

image-20201007175748653

  • HRRN例題:

image-20201007180105263

時間片輪轉調度算法RR

image-20201008150220842

  • RR例題

    • 時間片大小爲2情況:

      image-20201008145601465image-20201008145627089

    image-20201008145644629

    最後的運行流程圖:

    image-20201008145757946

    • 時間片大小爲5情況:

      image-20201008145938524

補充:

  • 時間片太大的影響:如果時間片太大,使得每個進程都可以在一個時間片內完成,則時間片輪轉調度算法會退化爲先來先服務調度算法,並且會增大進程響應時間。因此時間片不能太大。
  • 時間片太小的影響:如果時間片太小,我們知道,進程調度、切換是有時間代價的(保存、恢復運行環境),因此這樣的話會導致進程切換過於頻繁,系統會花大量時間來處理進程切換,從而導致實際用於進程執行的時間比例減少。
優先級調度算法

image-20201008152411598

  • 例題

    • 非搶佔式的優先級調度算法:

      image-20201008150852742

    • 搶佔式的優先級調度算法:

      image-20201008151221693

extra

  • 就緒隊列未必是隻有一個的,可以按照不同優先級來組織;另外也可以把優先級高的進程排在更靠近對頭的位置
  • 根據優先級是否可以動態改變,可將優先級分爲靜態優先級動態優先級兩種;
    • 靜態優先級:創建進程時確定,之後一直不變
    • 動態優先級:創建進程時有一個初始值,之後根據情況動態地調整優先級
  • 如何合理設置各進程優先級呢?通常來說
    • 系統進程優先級高於用戶進程
    • 前臺進程優先級高於後臺進程
    • I/0進程優先級高於計算型進程
  • 若採用動態優先級,什麼時候該調整?
    • 如果某進程在就緒隊列中等待了很久,適當提升優先級
    • 如果某進程佔用處理機運行了很久,適當降低優先級
    • 如果發現一個進程頻繁進行I/0操作,適當提升優先級
多級反饋隊列調度算法

image-20201008153258694

  • 例題:

    image-20201008153117802

死鎖

image-20201022160457079

死鎖的概念

image-20201009145923563

  • 簡單來說,當一組進程發生死鎖的情況下,這組死鎖進程中的每個進程,都在等待另一個死鎖進程所佔有的資源,或者說每個進程所等待的事件是該組中其他進程釋放所佔有資源

死鎖,飢餓,死循環

  • 死鎖:各進程互相等待對方手裏的資源,導致各進程都阻塞,無法向前推進的現象。
  • 飢餓:由於長期得不到想要的資源,某進程無法向前推進的現象。eg.SPF算法中的如果短進程一直進來,長進程得不到處理機就會飢餓。
  • 死循環:某進程執行過程中一直跳不出某個循環的現象。有時是因爲程序bug,有時候是故意寫出來的。(pv操作)

image-20201009150936475

死鎖產生的必要條件

image-20201009151437016

  1. 互斥條件:在一段時間內,某資源只能被一個進程所佔有,若其他進程請求該資源,那就只能等待,直到佔有該資源的進程用完釋放
  2. 不可搶佔條件:進程已獲得的資源未使用完之前不能被搶佔只能在進程使用完時由自己釋放
  3. 請求和保持條件:進程已經保持了至少一個資源,但又提出了新的資源請求,而該資源又被其他進程佔有,此時請求進程被阻塞,但又對自己已有的資源保持不放
  4. 循環等待條件:在發生死鎖時,必然存在一個【進程-資源】的循環鏈,即進程集合{P0,P1,P2…Pn}中:P0等待P1佔用的資源,P1等待P2佔用的資源…Pn等待P0佔用的資源

image-20201009152417463

  • 對不可剝奪資源的不合理分配,可能導致死鎖

死鎖的處理方法

預防死鎖

整體思路:破壞死鎖產生的四個必要條件中的一個或幾個

image-20201022160437390

破壞互斥條件
  • 互斥條件:只有對必須互斥使用的資源的爭搶纔會導致死鎖
  • 破壞策略:把只能互斥使用的資源改造爲允許共享使用,則系統不會進入死鎖狀態。
  • 缺點:並不是所有的資源都可以改造成共享使用的資源,並且爲了系統安全,很多地方還必須保護這種互斥性。因此很多的時候是無法破壞互斥條件的。

image-20201009153658886

破壞不可剝奪條件
  • 不可剝奪條件:進程所獲得的資源在未使用完之前,不能由其他進程強行奪走,只能主動釋放
  • 破壞策略
    • 當某個進程請求新的資源得不到滿足的時候,必須立刻釋放保持的所有資源,待以後需要時候再重新申請,即:即使某些資源尚未用完,也需要主動釋放,從而破壞了不可剝奪條件。
    • 當某個進程需要的資源被其他進程所佔有的時候,可以由操作系統協助,將想要的資源強行剝奪。這種方法需要考慮各進程的優先級。
  • 缺點
    • 實現起來複雜
    • 釋放已獲得的資源可能造成前一階段的失效,因此這種方法一般只適用於容易保存和恢復狀態的資源(CPU)
    • 反覆申請和釋放資源增加系統開銷,降低系統吞吐量
    • 使用第一個方案,表示只要暫時得不到某資源,前面所獲得資源全都得需要放棄,以後再申請。假如這種情況常發生,進程會飢餓。

image-20201009154244423

破壞請求和保持條件
  • 請求和保持條件:進程已經保持了至少一個資源,但又提出了新的資源請求,而該資源又被其他進程佔有,此時請求進程被阻塞,但又對自己已有的資源保持不放。
  • 破壞策略:採用靜態分配方法,即進程在運行前一次申請完所需要的全部資源,在它資源尚未滿足前,不讓它投入運行。一旦投入運行,這些資源就一直歸他所有,該進程就不會再請求別的任何資源。
  • 缺點:有些資源可能只需要用很短時間,因此如果進程的整個運行期間都一直保持着所有資源,就會造成嚴重的資源浪費,資源利用率極低。另外,該策略也可能導致某些進程飢餓。

image-20201009154702673

正因爲這種方法缺點太明顯,因此衍生出了第二種方法:

它允許一個進程只獲得初期所需的資源後,便開始運行。在運行過程中逐步釋放已分配給自己的、且用畢的全部資源,然後再請求新的所需資源。

破壞循環等待條件
  • 循環等待條件:存在一種進程資源的循環等待鏈,鏈中每個進程已獲得的資源同時被下一個進程所請求
  • 破壞策略:採用順序資源分配法
    • 給系統中資源編號
    • 規定每個進程必須按照編號遞增的順序請求資源,同類資源(編號相同資源)一次申請完
    • 一個進程只有佔有了小編號資源纔有資格申請大編號資源
  • 缺點:
    • 不方便添加新設備,有可能要重新分配編號嘛
    • 進程實際使用資源順序可能與編號遞增順序不同,會導致資源浪費
    • 必須按規定次序申請資源,用戶編程麻煩(謝謝你啊 還替我考慮那麼多

image-20201009155649878

避免死鎖

  • 用某種方法防止系統進入不安全狀態,從而避免死鎖(銀行家算法)
安全序列

安全序列:是指如果系統按照這種序列分配資源,則每個進程都能順利完成。只要能找出一個安全序列,系統就是安全狀態。當然,安全序列可能會有多個

image-20201009160734369

  • 不安全狀態:如果分配了資源之後系統找不出任何一個安全序列,系統就進入了不安全狀態。意味着之後可能所有進程都無法順利執行下去了。爲什麼說是可能呢?因爲假如存在進程提前歸還了資源,那麼系統也有可能重新回到安全狀態
  • 安全狀態、不安全狀態、死鎖
    • 系統處於安全狀態一定不會發生死鎖
    • 系統處於不安全狀態有可能發生了死鎖
    • 如果發生了死鎖一定處於不安全狀態
銀行家算法
  • 核心思想:在資源分配之前預先判斷這次分配是否會導致系統進入不安全狀態,以此決定是否答應資源分配請求
  • 引例:

image-20201009221753621

image-20201009221808544

那麼對於上述這個例子,OS是怎麼做的呢?

image-20201009222819458

  • 準備的數據結構:

    • 長度爲m一維數組Available表示還有多少可用資源
    • n*m矩陣Max表示各進程對資源的最大需求數
    • n*m矩陣Allocation表示已經給各進程分配了多少資源
    • Max - Allocation = Need 矩陣表示各進程最多還需要多少資源
    • 長度爲m一維數組Request表示進程此次申請的各種資源數
  • 銀行家算法步驟:

    • 檢查此次申請是否超過之前聲明的最大需求數
    • 檢查此次系統剩餘的可用資源是否還能滿足此次請求
    • 試探着分配,更改各數據結構
    • 用安全性算法檢查此次分配是否會導致系統進入不安全狀態
  • 安全性算法步驟:

    檢查當前剩餘的可用資源是否能夠滿足某個進程的最大需求,如果可以,就把該進程加入安全序列,並把該進程持有的資源全部回收

檢測和解除死鎖

  • 允許死鎖的發生,不過OS會負責檢測出死鎖的發生,然後採取某種措施解決死鎖

image-20201022160411857

檢測死鎖

  • 檢測死鎖的算法

簡單來說就是依次消除與不阻塞進程相連的邊直到無邊可消;但你要是非說嚴謹的話就是下面幾步

  1. 在資源分配圖中,找出既不阻塞又不是孤點的進程Pi (不阻塞—— 所申請的資源數量必須小於等於系統中已有空閒資源數量;不是孤點——與該進程至少有一個邊相連)。然後消去它的所有請求邊,分配邊,使之變爲孤點
  2. 進程Pi釋放的資源,可以喚醒某些因爲等待這些資源而阻塞的進程——原來阻塞進程可能變爲非阻塞進程
  3. 若剩下進程都能按照如上操作,消去圖中所有的邊,所有的進程結點都變成孤點,那稱該圖是 可完全簡化 的;反之則稱該圖是 不可完全簡化
  • 死鎖定理:如果某時刻系統的資源分配圖是 不可完全簡化的,那麼此時系統死鎖
解除死鎖

解除死鎖的方法:

  1. 資源剝奪法:掛起某些死鎖進程,並搶奪它的資源,將這些資源分配給其他的死鎖進程
  2. 撤銷進程法/終止進程法:強制撤銷部分、甚至全部死鎖進程,並剝奪這些進程的資源
  3. 進程回退法:讓一個或多個死鎖進程回退到足以避免死鎖的地步

內存

內存基礎知識

image-20201022160329434

  • 什麼是內存?內存是用於存放數據的硬件。程序執行前需要先放到內存中才能被CPU處理。

    image-20201013164419312

進程運行原理-指令

image-20201013165458590

由 x = x + 1這個代碼爲例,它被編譯後爲三條指令;

第一條指令是讓CPU進行數據傳送,把內存單元爲01001111的數據取出來取到地址爲00000011的寄存器當中

第二條指令是讓地址爲00000011的寄存器上的數據+1

第三條指令是讓CPU進行數據傳送,把地址爲00000011上的數據傳送到地址爲01001111的地方.

於是實現了 x = x + 1操作

ps:上述指令不是嚴謹的二進制指令,僅供參考。

單位換算

由於後續的學習,經常要進行內存之間的運算,而我們的單位往往需要統一,那麼接下來就講講單位換算

  • 1B=8b=2^3b

  • 1KB=1024B=2^10B

  • 1MB=1024KB=210KB=220B

  • 1GB=1024MB=210MB=220KB=2^30B

  • 1TB=1024GB=210GB=220MB=230KB=240B

邏輯地址

上面的指令操作提到了邏輯地址,那麼什麼是邏輯地址呢?

image-20201013171208992

eg. 0號同學入住的是房號爲5(N=5)的房間,那麼3(M=3)號同學入住的就是8(N+M=5+3=8)號房間;

寫程序-運行程序

image-20201013172103828

  • 編輯:程序員編輯代碼
  • 編譯:代碼編譯成若干個目標模塊(把高級語言翻譯爲機器語言
  • 鏈接:由鏈接程序把 目標模塊與所需庫函數 連接在一起,形成一個完整的裝入模塊
  • 裝入\裝載:由裝入程序裝入模塊裝入內存運行

鏈接

靜態鏈接
  • 裝入前鏈接成一個完整裝入模塊
  • 在程序執行之前,先將目標模塊以及它們所需的庫函數連接成一個完整的可執行文件(裝入模塊),之後不再拆開

image-20201013191036437

裝入時動態鏈接
  • 運行前邊裝入邊鏈接
  • 將各目標模塊裝入內存時,邊裝入邊鏈接的鏈接方式

image-20201013191117077

運行時動態鏈接
  • 運行時需要目標模塊才裝入並鏈接
  • 在程序執行中需要該目標模塊時,纔對它進行鏈接。其優點是便於修改和更新,便於實現對目標模塊的共享

image-20201013191223728

裝入\裝載

絕對裝入
  • 編譯時產生絕對地址
  • 地址由編譯器產生,而不是OS

image-20201013183938535

靜態重定位
  • 裝入時邏輯地址轉換爲物理地址/絕對地址
  • 轉換過程由裝入程序負責進行,裝入程序是OS的一部分

image-20201013190449917

動態重定位
  • 運行時將邏輯地址轉換爲物理地址,並設置重定位寄存器
  • 採用動態重定位方式裝入的作業,其地址變換工作是在每執行一條指令時完成的
  • 執行中允許OS有條件地將其移動

image-20201013190842596

內存管理概念

image-20201022160304377

內存空間的分配與回收

  • OS需要負責內存空間的分配與回收
    • 記錄哪些內存區域已經被分配出去了,哪些又屬於空閒狀態
    • 當進程運行結束之後,將進程佔用的內存空間回收
    • 內存這麼大,有很多位置可以放置內存,那麼又該怎麼分配內存空間?

image-20201015211348937

連續分配管理方式

  • 連續分配:指爲用戶進程分配的必須是一個連續的內存空間

image-20201022160222327

單一連續分配
  • 在這種分法中,內存被分爲系統區和用戶區
  • 系統區:用於存放OS相關數據
  • 用戶區:存放用戶進程相關數據
  • 內存中只能有一道用戶程序,用戶程序獨佔整個用戶區空間
  • 優點:實現簡單,無外部碎片;
  • 缺點:只能用於單用戶、單任務的OS中,有內部碎片,存儲區利用率極低

image-20201017155052815

固定分區分配
  • 固定分區目的:爲了能在內存中裝入多道程序,且這些程序之間又不會相互打擾
  • 如何實現:將整個用戶空間劃分爲若干個固定大小的分區,在每個分區中只裝入一道作業
  • 固定分區分配有兩種方法
    • 分區大小**相等:**缺乏靈活性,但適合用於用一臺計算機控制多個相同對象的場合
    • 分區大小**不等:**增加靈活性,可以滿足不同大小的進程需求。根據常在系統中運行的作業大小情況進行劃分

image-20201017155506303

那麼固定分區分配又是如何實現的呢?

  • 操作系統需要建立一個數據結構 —— 分區說明表,實現各個分區的分配與回收。每個表象對應一個分區,通常按照分區大小排列。每個表包含對應分區的:大小、起始地址、狀態

    image-20201017162252431

  • 當某用戶程序要裝入內存的時候,由OS內核程序根據用戶程序大小檢索該表,從中找到一個能滿足大小、未分配的分區。將之分配給該程序,然後修改狀態爲「已分配」

  • 優點:實現簡單,無外部碎片

  • 缺點

    • 當用戶程序太大的時候,可能所有的分區都不能滿足需求,此時不得不採用覆蓋技術來解決,但這會降低性能
    • 會產生內部碎片,內存利用率低
動態分區分配
  • 動態分區分配又稱爲可變分區分配。

  • 這種分配方式不會預先劃分內存分區,而是在進程裝入內存的時候,根據進程的大小動態地建立分區,並使分區的大小正好適合進程的需要。

  • 系統分區的大小和數目是可變的

  • 缺點:會產生很多外部碎片,雖然可以用【緊湊】技術去處理,但緊湊的時間代價很高

    image-20201017163335963

下面思考三個問題:

  1. 系統要用什麼樣的數據結構記錄內存的使用情況?

    通常使用 空閒分區表或者是空閒分區鏈

    空閒分區表:每個空閒分區對應一個表項

    空閒分區鏈:每個分區的起始部分和末尾部分分別設置前向指針和後向指針

    image-20201017163635023

  2. 當很多個空閒分區都能滿足需求的時候,應該選擇哪個分區進行分配呢?

    把一個新作業裝入內存的時候,需要按照一定的動態分區分配算法,從空閒分區表(空閒分區鏈)中選出一個分區分配給該作業。

  3. 如何進行分區的分配與回收操作?

    分配:

    在上面的圖示中,假如我們把一個4mb進程分配在了20MB處的話,我們只需要修改分區大小和起始地址即可

    image-20201017164819366

    假如我們分配在了4MB處的話,狀態由空閒變爲忙碌,則該行應該被刪除,假如用空閒分區鏈的話,就把該節點刪除

    image-20201017165013499

    回收

    假設一開始有個進程佔據了14MB處(10+4),跑完了需要回收,回收區的後面/前面有一個相鄰的空閒分區,那麼就合併

    image-20201017165628159

    假如回收區的前、後各由一個相鄰的空閒分區的話

    例:在20和10mb中間有一個4mb的進程需要進行回收

    image-20201017165906305

    假如回收區的前後都沒有相鄰的空閒分區的話

    假設有一個進程佔滿了14mb的地方,此進程需要被回收

    image-20201017170134212

  • 內部碎片,外部碎片

    • 內部碎片:位於一個操作系統分配的用於裝載進程的內存區域或頁面內部的空閒區域。
    • 外部碎片:位於任何兩個操作系統分配的用於裝載進程的內存區域或頁面之間的空閒區域,可以用緊湊技術進行解決

    image-20201017170829341

首次適應算法
  • 算法思想:每次都從低地址開始查找,找到第一個能滿足大小的空閒分區
  • 如何實現:空閒分區以地址遞增的次序排列,每次分配內存的時候順序查找空閒分區鏈(or空閒分區表),找到大小能滿足要求的第一個空閒分區

image-20201019154035820

最佳適應算法
  • 算法思想:動態分區分配是一種連續分配的管理方式,因此爲各進程分配的空間必須也是連續的一整片區域。因此爲了保證當大進程進來的時候有能連續的大片空間,可以儘可能多的留下大片空閒區,換句話說,就是大片的先不用,優先的把小空閒區給用了先。
  • 如何實現:空閒分區按容量遞增次序鏈接,每次分配內存的時候順序查找空閒分區鏈(or空閒分區表),找到大小能滿足要求的第一個空閒分區
  • 缺點:會產生很多的外部碎片

image-20201019155759288

最壞適應算法

爲了解決上述出現的 產生很多外部碎片 這個問題,我們衍生出了新的與之相對的算法:最壞適應算法

  • **算法思想:**每次分配的時候優先使用最大的連續空閒區,使得分配後剩餘的空閒區不會太小,方便使用;
  • 如何實現:空閒分區容量遞減次序鏈接。每次分配內存時候按照順序查找空閒分區鏈(or空閒分區表),找到大小能滿足要求的第一個空閒分區。
  • 缺點:每次都選最大的分區進行分配,會導致較大的連續空閒區被迅速消耗掉,有大進程來了,就沒內存空間可以用了。

image-20201019160300060

臨近適應算法

我們每次算法講到最後一個都是綜合類的算法,結合了前面算法的特點綜合的算法

不例外,我們這次也一樣:臨近時應算法

  • **算法思想:**回想一下 ,首次適應算法是從鏈頭開始找,低地址部分會出現小的空閒分區(外部碎片),而這些空閒分區部分我們往往用不上,因此會增加查找的開銷。那麼加入我們查找不從頭開始,而是從上次查找結束的位置開始檢索(因爲後面是還沒用到的部分,可以用的機率大點),就能減少查找開銷。
  • 如何實現:空閒分區以遞增遞增的順序排列(可排成一個循環鏈表),每次分配內存的時候從上次查找結束的位置開始查找空閒分區鏈(or空閒分區表),找到大小能滿足要求的第一個空閒分區。

image-20201019161625044

四種算法總結

image-20201019162144683

非連續分配管理方式

基本分頁存儲管理

image-20201022160151687

基本概念

image-20201019163349804

如何實現地址的轉換

回想我們之前所學的,進程在內存中連續存放的時候,OS是如何實現邏輯地址到物理地址的轉換的呢?

是通過重定位寄存器去保存 裝入模塊存放的 起始位置 + 目標內存單元相對於起始位置的偏移量

我們就能得到該在物理地址(絕對地址)中,我們的目標存放的地址了,同理,我們把這種思想轉移到了分頁技術中地址的轉換

以下面爲例:

  • 頁號:邏輯地址 / 頁面長度 取整 (本題中:頁號=80/50 = 1
  • 業內偏移量:邏輯地址 % 頁面長度 (本題中:頁內偏移量=80 % 50 = 30
  • 頁面在內存中的起始位置:OS用某種數據結構去進行記錄的 (本題中一號頁在內存中存放的起始位置=450

image-20201019165134603

爲了方便計算頁號、業內偏移量,頁面大小一般取2的整數冪,那麼接下來我們就來看看這種情況是什麼樣子的

紅色部分前20位,表示了是第幾頁;(這的前值的是從左往右數,如果嚴格按照二進制來說應該是後20位

後面12位是偏移值(這的前值的是從左往右數,如果嚴格按照二進制來說應該是前12位

加入我們知道了N號頁在內存中的起始地址(假設爲X),那麼我就知道我們已知的邏輯地址所對應的物理地址了

  • 結論:若每個頁面大小爲2^KB,用二進制數表達邏輯地址,那麼末尾K位是頁面偏移量。其餘部分代表頁號

image-20201019170219137

邏輯地址結構
  • 分頁存儲管理的邏輯地質結構由:頁內偏移量頁號組成

  • 若由K位表示頁內偏移量,說明系統中一個頁面大小是2^K個內存單元

  • 若由M位表示頁號,說明系統中,一個進程最多允許2^M個頁面

image-20201019171609549

頁表

上述我們有個遺留問題,我們如何知道頁號對應頁面 在 內存中的起始地址呢?

其實是通過頁表知道的,下面看看什麼是頁表

  1. 一個進程對應一張頁表

  2. 進程的每一頁對應一個頁表項

  3. 每個頁表項由【頁號】和【塊號】組成

  4. 頁表記錄進程頁面和實際存放的內存塊之間的對應關係

  5. 每個頁表項的長度是相同的,頁號是隱含的

    這句話是說明意思呢?意思是說 我們能夠通過頁表存放的起始地址頁表項長度,就可以找到各頁號所對應的頁表存放的位置

    image-20201019203053285

image-20201019202912635

基本地址變換機構

image-20201022160101385

  • 基本地址變換機構可以藉助進程的頁表將邏輯地址轉換爲物理地址
  • 通常會在系統中設置一個頁表寄存器(PTR),存放頁表在內存中的起始地址F頁表長度M
  • 進程未執行的時候,頁表的起始地址頁表長度放在進程控制塊PCB中,當進程被調度的時候OS內核會把他們放在頁表寄存器

(頁面大小爲2的整數冪)

設頁面大小爲L,邏輯地址A到物理地址E的變換過程:

  1. 計算頁號P頁內偏移量W(以十進制爲例:**頁號P = 邏輯地址A / 頁面大小L ;頁內偏移量W = 邏輯地址A % 頁面大小L ** 但計算機實際運行的時候,邏輯地址結構是固定不變的,因此計算機硬件可以更快得到二進制表示的頁號和頁內偏移量)

  2. 比較頁號P頁表長度M,如果P>=M,就產生越界中斷,否則繼續執行 (爲什麼等號也會算作越界中斷呢?因爲頁號是從0開始的,而頁表長度至少是1,因此P = M也會中斷哦 類似於數組越界)

  3. 頁表中頁表P對應的頁表項地址 = 頁表起始地址F + 頁號P * 頁表項長度;取出該頁表項內容b,即爲內存塊號

    頁表長度:指的是這個頁表中總共有幾個頁表項,就是有多少頁

    頁表項長度:指的是每個頁表項佔據了多大的存儲空間

    頁面大小:一個頁面佔多大的存儲空間

  4. 計算物理地址E = 內存塊號b * 頁面大小L + 頁內偏移量W ,用得到的物理地址E去訪存

說了那麼多,感覺是不是雲裏霧裏的,知道了一堆名詞,計算方式,但真正計算的時候仍然不會用?下面就來一道例題去實踐一下

image-20201022154324120

  • 頁號P = 邏輯地址A / 頁面大小L = 2500 / 1024 = 2 ; 頁內偏移量W = 邏輯地址A % 頁面大小L = 2500 % 1024 = 452
  • 判斷越界:頁號P對應內存塊號爲8 沒越界
  • 物理地址 E = 內存塊號 * 頁面大小 + 頁內偏移量 = 8 * 1024 + 452 = 8644 就是最後結果了
具有快表的地址變換機構
基本分段存儲管理
段頁式存儲管理

內存空間的擴展

  • 操作系統需要提供某種技術從邏輯上對內存空間進行擴充
  • 通常有三種技術:
    • 覆蓋技術
    • 交換技術
    • 虛擬存儲技術

image-20201015213523284

地址轉換

  • OS需要提供地址轉換功能,負責程序的邏輯地址與物理地址的轉換
  • 絕對裝入-編譯時產生絕對地址
  • 可重定位裝入-裝入時將邏輯地址轉換爲物理地址
  • 動態運行時裝入-運行時將邏輯地址轉換爲物理地址,需要設計重定位寄存器

image-20201015214304047

內存保護

內存保護可採取兩種辦法

  • 方法一:在CPU種設置一對上、下限寄存器,寄存進程的上、下限地址。進程的指令要訪問某個地址的時候,CPU檢查是否越界

    image-20201015215116282

  • 方法二:採用重定位寄存器(基址寄存器)和界地址寄存器(限長寄存器)進行越界檢查。其中,重定位寄存器中存放的是進程的起始物理地址界地址寄存器中存放的是進程的最大邏輯地址

    image-20201015215232038

覆蓋與交換

image-20201022160240209

覆蓋技術

  • 覆蓋是子啊同一個進程或程序中的

  • 思想:將程序分爲多個段(多個模塊),常用的段常駐內存,不常用的段在需要的時候才調入內存

    內存分爲一個固定去和若干個覆蓋區

    需要常駐內存的段放在固定區中,調入後就不再調出

    不常用的段放在覆蓋區需要用的時候調入內存用不到的時候調出內存

image-20201015220730717

  • 如下圖所示,假如程序A執行需要走如下幾個程序B、C…
  • B、C不能同時執行,我們就在物理內存中設置一個覆蓋區 用於存放B或者C,其中其大小是B、C中較大內存決定
  • 同理D、E、F也不能同時執行,因此也設立一個覆蓋區用於存儲

image-20201017150834371

交換技術

  • 交換是在不同進程(作業)之間的

  • 設計思想:內存空間緊張的時候,系統將內存中某些進程暫時換出外存,把外存中某些已具備運行條件的進程換入內存(進程在內存與磁盤間動態調度)

  • 這種技術其實在上面的處理機調度一節層次調度中的中級調度我們也有了解過了

    image-20201017152832202

  • 暫時換出外存等待的進程狀態爲掛起狀態(掛起態)

  • 掛起態可以細分爲就緒掛起和阻塞掛起兩種狀態 - 複習下7態模型吧

    image-20201017152921895

下面思考三個問題

  1. 應該在外存(磁盤)的什麼位置保存被換出的進程?

    答:具有兌換功能的操作系統中,通常把磁盤空間分爲文件區對換區兩部分;

    文件區主要用於存放文件,主要追求存儲空間的利用率,因此對文件區空間的管理採用離散分配方式

    對換區空間只佔磁盤空間的小部分,被換出的進程數據就存放在對換區,由於對換的速度直接影響到系統的整體速度,因此對換區空間的管理主要追求換入換出速度,因此通常採用連續分配方式

    對換區的I/O速度比文件區的更快

  2. 什麼時候應該交換?

    答:交換通常在許多進程運行且內存吃緊時進行,而系統負荷降低就暫停。例如:在發現許多進程運行時經常發生缺頁,就說明內存緊張,此時可以換出一些進程;如果缺頁率明顯下降,就可以暫停換出。

  3. 應該換出哪些進程?

    1. 可優先換出阻塞進程
    2. 可換出優先級低的進程
    3. 爲了放置優先級低的進程在被調入內存後很快又被換出,有的系統還會考慮進程在內存的駐留時間
    4. PCB會常駐內存,是不會被換出外存的

文件系統

越界

  • 物理地址 E = 內存塊號 * 頁面大小 + 頁內偏移量 = 8 * 1024 + 452 = 8644 就是最後結果了
具有快表的地址變換機構
基本分段存儲管理
段頁式存儲管理

內存空間的擴展

  • 操作系統需要提供某種技術從邏輯上對內存空間進行擴充
  • 通常有三種技術:
    • 覆蓋技術
    • 交換技術
    • 虛擬存儲技術
      image-20201015213523284

地址轉換

  • OS需要提供地址轉換功能,負責程序的邏輯地址與物理地址的轉換
  • 絕對裝入-編譯時產生絕對地址
  • 可重定位裝入-裝入時將邏輯地址轉換爲物理地址
  • 動態運行時裝入-運行時將邏輯地址轉換爲物理地址,需要設計重定位寄存器

image-20201015214304047

內存保護

內存保護可採取兩種辦法

  • 方法一:在CPU種設置一對上、下限寄存器,寄存進程的上、下限地址。進程的指令要訪問某個地址的時候,CPU檢查是否越界

image-20201015215116282

  • 方法二:採用重定位寄存器(基址寄存器)和界地址寄存器(限長寄存器)進行越界檢查。其中,重定位寄存器中存放的是進程的起始物理地址界地址寄存器中存放的是進程的最大邏輯地址

image-20201015215232038

覆蓋與交換

image-20201022160240209

覆蓋技術

  • 覆蓋是子啊同一個進程或程序中的

  • 思想:將程序分爲多個段(多個模塊),常用的段常駐內存,不常用的段在需要的時候才調入內存

    內存分爲一個固定去和若干個覆蓋區

    需要常駐內存的段放在固定區中,調入後就不再調出

    不常用的段放在覆蓋區需要用的時候調入內存用不到的時候調出內存

image-20201015220730717

  • 如下圖所示,假如程序A執行需要走如下幾個程序B、C…
  • B、C不能同時執行,我們就在物理內存中設置一個覆蓋區 用於存放B或者C,其中其大小是B、C中較大內存決定
  • 同理D、E、F也不能同時執行,因此也設立一個覆蓋區用於存儲

image-20201017150834371

交換技術

  • 交換是在不同進程(作業)之間的

  • 設計思想:內存空間緊張的時候,系統將內存中某些進程暫時換出外存,把外存中某些已具備運行條件的進程換入內存(進程在內存與磁盤間動態調度)

  • 這種技術其實在上面的處理機調度一節層次調度中的中級調度我們也有了解過了

image-20201017152832202

  • 暫時換出外存等待的進程狀態爲掛起狀態(掛起態)

  • 掛起態可以細分爲就緒掛起和阻塞掛起兩種狀態 - 複習下7態模型吧
    image-20201017152921895

下面思考三個問題

  1. 應該在外存(磁盤)的什麼位置保存被換出的進程?

    答:具有兌換功能的操作系統中,通常把磁盤空間分爲文件區對換區兩部分;

    文件區主要用於存放文件,主要追求存儲空間的利用率,因此對文件區空間的管理採用離散分配方式

    對換區空間只佔磁盤空間的小部分,被換出的進程數據就存放在對換區,由於對換的速度直接影響到系統的整體速度,因此對換區空間的管理主要追求換入換出速度,因此通常採用連續分配方式

    對換區的I/O速度比文件區的更快

  2. 什麼時候應該交換?

    答:交換通常在許多進程運行且內存吃緊時進行,而系統負荷降低就暫停。例如:在發現許多進程運行時經常發生缺頁,就說明內存緊張,此時可以換出一些進程;如果缺頁率明顯下降,就可以暫停換出。

  3. 應該換出哪些進程?

    1. 可優先換出阻塞進程
    2. 可換出優先級低的進程
    3. 爲了放置優先級低的進程在被調入內存後很快又被換出,有的系統還會考慮進程在內存的駐留時間
    4. PCB會常駐內存,是不會被換出外存的

文件系統