目錄
- 前言
- 內容大綱
- 行程
- 什么是行程
- 行程的控制結構
- 行程的狀態
- 行程的背景關系切換
- 執行緒
- 什么是執行緒
- 執行緒與行程的對比
- 執行緒的背景關系切換
- 執行緒的模型
- 調度
- 調度原則
- 調度演算法
- 好文推薦
前言
歡迎來到作業系統系列,依然采用圖解 + 大白話的形式來講解,讓小白也能看懂,幫助大家快速科普入門
本篇開始介紹行程、執行緒、協程,相信很多小白們對這幾個概念理解的不清晰,這里全部給你們安排的明明白白,我們開始進入正文吧
內容大綱

小故事
小明(作業系統)開了一家互聯網小公司,因為準備同時開發A與B兩個軟體,所以小明請了兩個開發團隊來做這件事情,分別是小王開發團隊與小李開發團隊,可是公司特別小,不僅只有一個房間(C P U),而且房間(C P U)只能容納一個開發團隊,為了能兩個軟體開發不被耽誤,小明(作業系統)決定,上午小王團隊開發,下午小李團隊開發(這個程序稱為調度),
小李(行程)與小王(行程)身為團隊負責人,他們要操心的事情比較多,需要對軟體進行分析整理,做架構設計,最后再把任務細化分配給團隊的每個程式員(執行緒),在團隊交換的房間的時候,還需要把整個軟體開發進度記錄下來,方便下次接著開發,相比程式員就輕松多了,每個人只負責一小塊,需要記錄的也只一小塊,
通過這個小故事,大伙也看出來了,一個行程管理著多個執行緒,就像團隊負責人(行程)管理著多個程式員(執行緒)一樣,
行程
什么是行程
你打開網易云音樂會產生一個行程 ,你打開QQ會產生一個行程 ,你電腦上運行的程式都是行程 ,行程就是這么簡單暴力,
現在我們思考一個問題,有一個行程讀取硬碟里的檔案,這個檔案特別大,需要讀取很長時間,如果 C P U 一直傻傻的等硬碟回傳資料,那 C P U 的利用率是非常低的,
就像燒開水,你會傻傻等水燒開嗎?很明顯,這段時間完全可以去做其他的事情(比如玩玩賽博朋克2077),水燒開了再過來把水倒入水杯中,這樣不香嗎?
C P U 也是一樣,它發現 行程 在讀取硬碟檔案,不需要阻塞等待硬碟回傳資料,直接去執行其他行程 ,當硬碟回傳資料時,C P U 會收到 中斷 的信號,于是 C P U 再回到之前的 行程 繼續運行

這種多程式 交替執行 的方式,就是 C P U 管理多行程初步思想,
可能會有人問了, 交替執行會不會很慢,這個不用擔心,因為 C P U 的執行速度與切換速度非常的快,可能就是幾十或幾百毫秒,超出了人類的感知,一秒鐘內可能就交替運行了多個行程,所以給我們產生 并行 的錯覺,其實這叫并發,
單核核 多行程交替執行 就是并發,多行程在多核運行就是并行,
行程的控制結構
創造任何東西的時候,都要先有形,才有物,你造房子、造汽車或造其他東西,都要有設計圖(結構),再根據設計圖來創造, 行程也不例外,它也有屬于自己的設計圖,那就是 行程控制塊(process control block,PCB),后面就簡稱 P C B 好了
P C B的結構資訊
P C B是 行程 存在的唯一標識,這意味一個 行程 一定會有對應的PCB,行程消失,P C B也會隨之消失
- 行程描述資訊
- 行程唯一的標記符,類似唯一id
- 用戶識別符號,行程歸屬的用戶,用戶識別符號主要為共享和保護服務
- 行程控制和管理資訊
- 行程當前狀態,比如運行、就緒、阻塞等,作為處理機分配調度的依據
- 行程優先級,描述行程搶占處理機的優先級,優先級高的行程可以優先獲得處理機
- 資源分配清單
- 用于說明有關記憶體地址空間或虛擬地址空間的狀況,所打開檔案的串列和所使用的輸入/輸出設備資訊
- CPU 相關資訊
- 指 C P U 中各暫存器值,當行程被切換時,C P U狀態資訊都必須保存在相應的 P C B 中,以便行程重新執行時,能再從斷點繼續執行,
P C B組成的佇列
P C B通過鏈表的方式進行組織,把具有相同狀態的行程鏈在一起,組成各種佇列
-
將所有處于就緒狀態的 行程 鏈在一起,稱為就緒佇列
-
把所有因等待某事件而處于等待狀態的 行程 鏈在一起就組成各種阻塞佇列

行程的狀態
通過觀察,我們發現行程執行的程序遵循這樣的 運行-暫停-運行 規律,雖然看起來十分簡單,但是它的背后涉及到了行程狀態的轉換
行程三態
行程的執行期間,至少具備三種基本狀態,即運行態、就緒態、阻塞態,

上圖狀態的意義
- 運行態(Runing):時刻行程占用 C P U
- 就緒態(Ready):可運行,但因為其他行程正在運行而暫停停止
- 阻塞狀態(Blocked):該行程等待某個事件(比如IO讀取)停止運行,這時,即使給它CPU控制權,它也無法運行
上圖狀態轉換流程
- C P U 調度緒態行程執行,進入運行狀態,時間片使用完了,回到就緒態,等待 C P U 調度
- C P U 調度緒態行程執行,進入運行狀態,執行IO請求,進入阻塞態,IO請求完成,CPU收到 中斷 信號,就緒態,等待 C P U 調度
行程五態
在三態基礎上,做一次細化,出現了另外兩個基本狀態,創建態和結束態,

上圖狀態的意義
- 創建態(new):行程正在被創建
- 就緒態(Ready):可運行,但因為其他行程正在運行而暫停停止
- 運行態(Runing):時刻行程占用 C P U
- 結束態(Exit):行程正在從系統中消失時的狀態
- 阻塞狀態(Blocked):該行程等待某個事件(比如IO讀取)停止運行,這時,即使給它CPU控制權,它也無法運行
狀態的變遷
- NULL => 創建態(new):一個新行程被創建時的第一個狀態
- 創建態(new) => 就緒態(Ready):當行程創建完成,進入就緒態
- 就緒態(Ready)=> 運行態(Runing):C P U 從就緒佇列選擇行程執行,進入運行態
- 運行態(Runing)=> 結束態(Exit):當行程已經運行完成或出錯時,進入結束狀
- 運行態(Runing) => 就緒態(Ready):分配給行程的時間片使用完,進入就緒態
- 運行態(Runing) => 阻塞狀態(Blocked): 行程執行等待事件,進入阻塞態
- 阻塞狀態(Blocked) => 就緒態(Ready):行程事件完成,C P U 收到 中斷 信號 ,進入就緒態
行程七態
其實行程還有一種狀態叫掛起態,掛起態代表該行程不會占用記憶體空間,它會被換出到硬碟空間保存,當需要使用它的時候,會被換入,加載到記憶體,掛起態可以分為下面兩種
- 阻塞掛起狀態:行程在外存(硬碟)并等待某個事件的出現
- 就緒掛起狀態:行程在外存(硬碟),但只要進入記憶體,即刻立刻運行
結合上述的兩種掛起態,就組成了行程七態

從上圖我們發現,創建態、就緒態、運行態,阻塞掛起態、阻塞態都可以轉入掛起態,這時問題就產生了,什么情況會轉入 掛起態 ,什么情況又會從 掛起態 轉入到 非掛起態(就緒態與阻塞態), 作業系統會根據當前資源狀況和性能要求與行程的優先級來進行掛起與激活操作,沒有固定的說法,
行程的背景關系切換
C P U把一個行程切換到另一個行程運行的程序,稱為行程背景關系切換,
在說行程背景關系切換之前,先來聊聊 C P U 背景關系切換
C P U背景關系 是指 C P U 暫存器 和 程式計數器
- C P U 暫存器 是 C P U 內置的容量小,速度極快的快取
- 程式計數器是用來存盤 是 C P U 正在執行的指令位置或即將執行的下一條指令位置
C P U 背景關系切換 就很好理解了,就是把前一個任務的 C P U背景關系 保存起來,然后在加載當前任務的 C P U背景關系,最后再跳轉到 程式計數器 所指的新位置,運行任務,
上面說到所謂的「任務」,主要包含行程、執行緒和中斷,所以,可以根據任務的不同,把 CPU 背景關系切換分成: 行程背景關系切換、執行緒背景關系切換和中斷背景關系切換,
行程的背景關系是怎么切換的
首先行程是由內核管理與調度的,所以 行程背景關系切換 只發生在內核態,行程背景關系切換的內容包含用戶空間資源(虛擬記憶體、堆疊、全域變數等)與內核空間資源(內核堆疊、暫存器等),
在做背景關系切換的時候,會把前一個 行程 的背景關系保存到它的 P C B 中,然后加載當前 行程 的 P C B 背景關系到 C P U 中,使得 行程 繼續執行

發生行程背景關系切換的場景
- 為了保證所有行程可以得到公平調度,CPU 時間被劃分為一段段的時間片,這些時間片再被輪流分配給各個行程,這樣,當某個行程的時間片耗盡了,切換到其它正在等待 CPU 的行程運行
- 行程在系統資源不足(比如記憶體不足)時,要等到資源滿足后才可以運行,這個時候行程也會被掛起,并由系統調度其他行程運行,
- 當行程通過睡眠函式 sleep 這樣的方法將自己主動掛起時,自然也會重新調度,
- 當有優先級更高的行程運行時,為了保證高優先級行程的運行,當前行程會被掛起,由高優先級行程來運行
- 發生硬體中斷時,CPU 上的行程會被中斷掛起,轉而執行內核中的中斷服務程式,
執行緒
什么是執行緒
在早期作業系統都是以 行程 為獨立運行的基本單位,直到后面,計算機科學家又提出了更小的能獨立運行的基本單位,它就是執行緒,
在現代作業系統,行程是最小的資源分配單位,執行緒是最小的運行單位,一個行程下面能有一個或多個執行緒,每個執行緒都有獨立一套的暫存器和堆疊,這樣可以確保執行緒的控制流是相對獨立的,

執行緒帶來的好處有以下幾點
- 一個行程中可以同時存在多個執行緒
- 讓行程具備多任務并行處理能力
- 同行程下的各個執行緒之間可以共享行程資源 (同行程內的多執行緒通信十分簡單高效)
- 更輕量與高效
執行緒帶來的壞處有以下幾點
- 因為行程資源共享,所以會產生資源競爭,需要通過鎖機制來協同
- 當行程中的一個執行緒奔潰時,會導致其所屬行程的所有執行緒奔潰(一般游戲的用戶設計不會采用多執行緒方式)
執行緒與行程的對比
- 行程是最小的資源(包括記憶體、打開的檔案等)分配單位,執行緒是最小的運行單位
- 行程擁有一個完整的資源平臺,而執行緒只獨享必不可少的資源,如暫存器和堆疊
- 執行緒同樣具有就緒、阻塞、執行三種基本狀態,同樣具有狀態之間的轉換關系(和行程大同小異)
- 執行緒的創建、終止時間比行程快,因為行程在創建的程序中,還需要資源管理資訊,比如記憶體管理資訊、檔案管理資訊,所以執行緒在創建的程序中,不會涉及這些資源管理資訊,而是共享它們(執行緒管理的資源較少)
- 同一個行程內的執行緒切換比行程切換快,因為執行緒具有相同的地址空間(虛擬記憶體共享),這意味著同一個行程的執行緒都具有同一個頁表,那么在切換的時候不需要切換頁表,而對于行程之間的切換,切換的時候要把頁表給切換掉,而頁表的切換程序開銷是比較大的
- 由于同一行程的各執行緒間共享記憶體和檔案資源,那么在執行緒之間資料傳遞的時候,就不需要經過內核了,這就使得執行緒之間的資料互動效率更高了
執行緒比行程不管是時間效率,還是空間效率都要高
執行緒的背景關系切換

當行程只有一個執行緒時,可以認為行程等于執行緒,執行緒背景關系的切換分兩種情況
- 不同行程的執行緒,切換的程序就跟行程背景關系切換一樣
- 兩個執行緒是屬于同一個行程,因為虛擬記憶體是共享的,所以在切換時,虛擬記憶體這些資源就保持不動,只需要切換執行緒的私有資料、暫存器等不共享的資料
所以執行緒的背景關系切換相比行程,開銷要小很多
執行緒的模型
在說執行緒模式之前,先介紹3個概念
- 內核執行緒:在內核空間就實作的執行緒,由內核管理
- 用戶執行緒:在用戶空間實作的執行緒,不歸內核管理,是由用戶態通過執行緒庫完成執行緒的管理(用戶態是指執行緒或行程在用戶空間運行)
- 輕量級行程:在內核中來支持用戶執行緒(用戶執行緒與內核執行緒的中間層,內核執行緒的高度抽象)
內核執行緒
因為內核執行緒是由內核空間管理,所以它的 結構執行緒控制塊(Thread Control Block, TCB) 在內核空間,作業系統對 T C B 是可見的
內核執行緒

內核執行緒有什么優點
- 內核執行緒的由內核空間管理,執行緒的創建、銷毀、調度等,都不用你操心,全自動化,屬于智能型
- 內核執行緒能利用cpu多核的特性,實作并行執行(因為由內核管理,非常智能)
- 內核執行緒阻塞,不會影響其他內核執行緒(因為由內核管理,非常智能)
內核執行緒有什么缺點
- 因為是內核管理,所以內核執行緒的大部分操作都涉及到內核態,即需要從用戶態切換到內核態,開銷較大
- 因為內核資源有限,所以無法大量創建內核執行緒
用戶執行緒
因為 用戶執行緒 在用戶空間,是由 用戶態 通過執行緒庫來管理,所以它的 結構執行緒控制塊(Thread Control Block, TCB) 也是在執行緒庫里面,對于作業系統而言是看到 T C B 的,它只能看到整個行程的 P C B(內核無法管理用戶執行緒,也感知不到用戶執行緒)

用戶執行緒有什么優點
- 因為用戶執行緒創建、銷毀、調度等都不走內核態,直接在用戶態進行操作,所以速度特別快
- 不依賴內核,可用于不支持執行緒技術的作業系統
- 可以大量創建用戶執行緒,不消耗內核資源
用戶執行緒有什么缺點
- 用戶執行緒創建、銷毀、調度需要自己實作相應執行緒庫
- 用戶執行緒阻塞會導致整個行程內的其他用戶執行緒阻塞(整個行程阻塞),因為內核感知不到用戶執行緒,所以無法去調度其他用戶執行緒
- 無法利用cpu多核特性,還是因為內核感知不到用戶執行緒
輕量級行程(Light-weight process,LWP)
輕量級行程(Light-weight process,LWP)可以理解成內核執行緒的高級抽象,一個 行程 可以有一個或多個L W P ,因為每個 L W P 與 內核執行緒 一對一映射,所以 L W P 都是由一個 內核執行緒 支持(用戶執行緒關聯L W P,即成為內核支持的用戶執行緒),
在大多數系統中,L W P與 普通行程 的區別也在于它只有一個最小的執行背景關系和調度程式所需的統計資訊,一般來說,一個行程 代表程式的一個實體,而 L W P 代表程式的執行執行緒,因為一個 執行執行緒 不像行程那樣需要那么多狀態資訊,所以 L W P 也不帶有這樣的資訊,
一對一模型(內核級執行緒模型)
L W P就是一對一模型,即 行程 只需要創建使用L W P ,因為一個 L W P 由一個 內核線 程支持,所以最終是內核管理執行緒,可以調度到其他處理器上(再簡單點解釋,直接使用內核執行緒)

一對一模型(1:1)的優缺點就多說,上面介紹內核執行緒的時候已經說過了,但是值得一提的是,jvm采用的就是該模型實作的執行緒,在java中啟動一個執行緒需要謹慎
一對多模型(用戶級執行緒模型)
一對多模型,即多個用 戶級執行緒 對用到同一個 L W P 上實作,因為是用戶態通過用戶空間的執行緒庫對執行緒管理,所以速度特別快,不會涉及到用戶態與內核態的轉換

一對多模型(n:1)的優點缺點其物體現在用戶級執行緒上面,用戶執行緒的優缺點前面說過,這里不做過多概述,值得一提的是python中的協程就是通過該模型實作,
多對多模型(兩級執行緒模型)
多對多模型是集各家所長所誕生的產物,它充分吸收前兩種執行緒模型的優點且盡量避免它們的缺點,
首先它區別于多對一模型,多對多模型行程內的 多用戶執行緒 可以系結不同的內核執行緒 ,這點與 一對一模型 類似,其次又區別于一對一模型,行程內的 多用戶執行緒 與 內核執行緒 不是一對一系結,而是動態系結,當某個 內核執行緒 因系結的 用戶執行緒 執行阻塞操作,讓出 C P U 時,系結該 內核執行緒 的其他 用戶執行緒 可以解綁,重新系結到其他 內核執行緒 繼續運行,
所以多對多模型(m:n),即不是多對一模型完全靠自己實作的執行緒庫調度,也不是一對一模型完全靠作業系統調度,而是一個中間態系統(負責自身調度與作業系統調度的協同作業),最后提一句Go語言使用的是多對多模型,這也是其高并發的原因,它的執行緒模型與Java中的ForkJoinPool非常類似,

多對多模型優點
- 兼具多對一模型的輕量
- 由于對應了多個內核執行緒,則一個用戶執行緒阻塞時,其他用戶執行緒仍然可以執行
- 由于對應了多個內核執行緒,則可以實作較完整的調度、優先級等;
多對多模型缺點
- 實作復雜(因為這種模型的高度復雜性,作業系統內核開發者一般不會使用,所以更多時候是作為第三方庫的形式出現)
調度
調度原則
CPU 利用率
- 運行程式發生了I/O 事件的請求,因此阻塞,導致行程在等待硬碟的資料回傳,這樣的程序,勢必會造成 C P U 突然的空閑,所以為了提高 C P U 利用率,發生等待事件使 C P U 空閑的情況下,調度程式需要從就緒佇列中選擇一個行程來運行,(PS:調度程式應確保 C P U 一直保持匆忙的狀態,可提高 C P U 的利用率)
系統吞吐量
- 程式執行某個任務花費的時間會比較長,如果這個程式一直占用著 C P U,會造成系統吞吐量的降低,所以要提高系統的吞吐率,調度程式要權衡長任務和短任務行程的運行完成數量,(吞吐量表示的是單位時間內 C P U 完成行程的數量,長作業的行程會占用較長的 C P U 資源,因此會降低吞吐量,相反,短作業的行程會提升系統吞吐量)
周轉時間
- 從行程開始到結束的程序中,實際上是包含兩個時間,分別是行程運行時間和行程等待時間,這兩個時間總和就稱為周轉時間,行程的周轉時間越小越好,如果行程的等待時間很長,而運行時間很短,那周轉時間就很長,調度程式應該避免這種情況發生,(周轉時間是行程運行和阻塞時間總和,一個行程的周轉時間越小越好)
等待時間
- 處于就緒佇列的行程,也不能等太久,希望這個等待的時間越短越好,因為可以使行程更快的在 C P U 中執行,所以就緒佇列中,行程的等待時間,也是調度程式所需要考慮的原則(這個等待時間不是阻塞狀態的時間,而是行程處于就緒佇列的時間,等待時間越長,用戶越不滿意),
回應時間
- 對于滑鼠、鍵盤這種互動式比較強的應用,我們當然希望它的回應時間越快越好,否則就會影響用戶體驗了,所以,對于互動式比較強的應用,回應時間也是調度程式需要考慮的原則( 用戶提交請求到系統第一次產生回應所花費的時間,在互動式系統中,回應時間是衡量調度演算法好壞的主要標準),
總之就是 要快!
調度演算法
不同的演算法適用不同的場景,下面介紹幾個單核中常見的調度演算法
先進先出演算法(First Come First Severd, FCFS)
先進先出演算法簡稱 F C F S,顧名思義,誰先來,誰先被 C P U 執行,后到的就乖乖排隊等待,十分簡單的演算法,C P U每次調度 就緒佇列 的第一個行程,直到行程退出或阻塞,才會把該行程入隊到隊尾,然后接著繼續調度第一個行程,依此類推,

F C F S演算法看似很公平,但是當一個長作業先運行了,后面的短作業等待的時間就會很長,所以不利于短作業,會降低系統吞吐量,
F C F S對長作業有利,適用于 C P U 繁忙型作業的系統,而不適用于 I/O 繁忙型作業的系統,
最短作業優先演算法(Shortest Job First, SJF)
同樣也是顧名思義,它會優先選擇運行時間最短的行程,有助于提高系統吞吐量,但是對長作業不利,所以很容易造成一種極端現象,比如,一個 長作業 在就緒佇列等待運行,而這個就緒佇列有非常多的短作業,最終使得 長作業 不斷的往后推,周轉時間變長,致使長作業長期不會被運行(適用于 I/O 繁忙型作業的系統),

高回應比優先演算法 (Highest Response Ratio Next, HRRN)
因為前面的「先進先出演算法」和「最短作業優先演算法」都沒有很好的權衡短作業和長作業,所以高回應比優先演算法主要是權衡了短作業和長作業,
每次進行行程調度時,先計算「回應比優先權」,然后把「回應比優先權」最高的行程投入運行,

從上面的公式,可以發現:
如果兩個行程的「等待時間」相同時,「要求的服務時間」越短,「優先權」就越高,這樣短作業的行程容易被選中運行(如果等待時間較短,行程的運行時間越短,優先權就會越高 => 等待時間較短的短作業行程)
如果兩個行程「要求的服務時間」相同時,「等待時間」越長,「優先權」就越高,這就兼顧到了長作業行程,因為行程的回應比可以隨時間等待的增加而提高,當其等待時間足夠長時,其回應比便可以升到很高,從而獲得運行的機會(如果要求服務時間比較長,行程的等待時間越長,優先權就會越高 => 等待時間較長的長作業行程)
時間片輪轉(Round Robin, RR)演算法
時間片輪轉是最古老、最簡單、最公平且使用最廣的演算法,給每個行程分配相同時間片(Quantum),允許行程在該時間段中運行,

- 如果時間片用完,行程還在運行,將會把此行程放入就緒佇列,并繼續調度另外一個行程,依此類推
- 如果該行程在時間片結束前阻塞或結束,則調度另外一個行程
- 行程時間片用完,需要被重新分配時間片
需要注意的是,如果時間片設定的太短,會導致CPU背景關系切換態頻繁,太長又可能引起對短作業行程的回應時間變長,所以時間片設為 20ms~50ms 通常是一個比較合理的折中值
最高優先級(Highest Priority First,HPF)演算法
前面的「時間片輪轉演算法」讓所有的行程同等重要,不偏袒誰,大家的運行時間都一樣,但是,對于多用戶計算機系統就有不同的看法了,它們希望調度是有優先級的,希望調度程式能從就緒佇列中選擇最高優先級的行程運行,這就是最高優先級(Highest Priority First,HPF)演算法,
行程的優先級可以分為:
- 靜態優先級:創建行程時候,已經確定優先級,整個運行時間優先級都不會變化
- 動態優先級:根據行程的動態變化調整優先級,比如行程運行時間增加,則降低其優先級,如果行程等待時間(就緒佇列的等待時間)增加,則提高優先級,
有兩種處理優先級高的方法:
- 非搶占式:當就緒佇列中出現優先級高的行程,運行完當前行程,再選擇優先級高的行程,
- 搶占式:當就緒佇列中出現優先級高的行程,當前行程掛起,調度優先級高的行程運行,
但是依然有缺點,可能會導致低優先級的行程永遠不會運行,
多級反饋佇列(Multilevel Feedback Queue)演算法
多級反饋佇列(Multilevel Feedback Queue)演算法 是基于「時間片輪轉演算法」和「最高優先級演算法」演進而來,如同它的名字一樣,根據優先級分組成多個佇列,在演算法中涉及兩個概念:
- 「多級」表示有多個佇列,每個佇列優先級從高到低,優先級越高的佇列擁有的時間片越短
- 「反饋」 表示有新的行程進入優先級高的佇列時,停止當前運行行程,去運行優先級高的佇列

作業流程:
- 多個佇列,賦予每個佇列不同的優先級,每個佇列優先級從高到低,同時優先級越高時間片越短
- 新進的 行程 會被放入 第一級佇列 尾部,按先來先服務的原則排隊等待被調度,如果第一級佇列時間片用完,還有行程沒有執行,把第一級佇列剩余的行程 放入 第二級佇列的尾部,依此類推
- 當優先級高佇列為空,正在運行低優先級佇列的行程時,有新行程 進入 高優先級佇列,這時立即停止當前運行行程,把當前行程放入 原佇列 尾部,轉而去 運行 高優先級佇列的行程,
可以發現,對于短作業可能可以在第一級佇列很快被處理完,對于長作業,如果在第一級佇列處理不完,可以移入下次佇列等待被執行,雖然等待的時間變長了,但是運行時間也會更長了,很好的兼顧了長短作業,同時有較好的回應時間,
好文推薦
15分鐘!一文幫小白搞懂作業系統之記憶體
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/239047.html
標籤:其他
上一篇:軟考網路工程師備考經驗
