在操做系統中,進程和線程是極爲重要的概念,這篇文章主要總結了進程、線程的基本概念及進程的調度。算法
進程(process
)是具備必定獨立功能的程序關於某個數據集合上的一次運行活動。在傳統 OS
中,進程是系統進行資源分配和調度的基本單位。進程是一個正在運行程序的實例,包括程序代碼、程序計數器和寄存器的值以及系統資源(如打開的文件)等。數組
在某一瞬間,一個 CPU
中只能運行一個進程,它是在各個進程之間來回切換的,每一個進程執行的速度也不肯定。bash
進程和程序間的聯繫和區別以下:併發
爲了實現進程,操做系統維護了一張進程表(結構數組),每一個進程佔用一個進程表項(進程控制塊 PCB
),它是進程存在的惟一標誌。該表項包含了進程狀態的重要信息,包括進程標識符、狀態、優先級、程序計數器、堆棧指針、寄存器等;函數
對進程的管理就是對經過 PCB
的組織管理來實現的。因爲保存了在進程的狀態變化時的必要信息,在中斷一個正在執行的進程,並在後來恢復時,就好像進程從未中斷過。它是支持多進程和提供多處理的關鍵。spa
以下圖是進程的三種狀態的狀態圖。一個進程的三種狀態是:操作系統
CPU
執行;CPU
外的全部資源;CPU
,也不能運行。進程之間主要有四種轉換關係:線程
CPU
;I/O
請求完成;I/O
請求;線程(thread
)是進程中的一條執行流程。在引入線程的操做系統中,進程是擁有資源的基本單位;而線程是 CPU
調度和分派的基本單位。3d
一個進程中能夠有多個線程,多個線程能夠併發執行,它們之間共享相同的地址空間。但若是一個線程崩潰,可能會致使其所屬進程的全部線程崩潰。指針
有三種線程的實現方式:
用戶線程
用戶線程是把整個線程包放在用戶空間中,不依賴於操做系統的內核,因此它能夠在不支持線程的操做系統上實現。能夠用一組用戶級的線程函數庫來實現線程。
每一個進程都須要私有的線程表,用來跟蹤記錄該進程中線程的狀態信息,不過僅記錄每一個線程的程序計數器、堆棧指針、寄存器和狀態等,該線程表由運行時系統管理。並且用戶線程的切換由線程庫函數來完成,不須要用戶態、核心態切換,因此線程調度速度特別快。另外,也容許每一個進程都擁有自定義的線程調度算法。
但若是一個線程發起系統調用而阻塞,儘管其餘線程能夠運行,但整個進程都會阻塞。當一個線程開始運行後,除非它主動較交出 CPU
,不然它所在的進程中的其餘線程將沒法運行。
內核線程
內核線程在操做系統的內核中實現,由內核來完成對線程的建立、終止和管理。
因爲線程的建立、終止和切換經過系統調用執行,由內核完成的,其系統開銷比較大;
但在一個進程中,若是某個內核線程發起系統調用而被阻塞,並不會影響其餘使用內核線程的運行;
輕量級進程
輕量級進程是內核支持的用戶線程。一個進程能夠有一個或多個輕量級進程,每一個輕量級進程由一個單獨的內核線程來支持。而輕量級進程內部能夠對應多個用戶線程。
處理機調度是當有多個進程(線程)競爭 CPU
時,調度程序須要從從就緒隊列中挑選下一個佔用 CPU
運行的進程。
調度算法是爲了解決經過什麼樣的準則來挑選就緒對列中的哪個進程來執行。在每次調度時須要決定在下一個 CPU
計算時將哪一個進程交給 CPU
。
先來先服務算法FCFS
根據進程進入就緒態的前後順序排列。當進程進入阻塞態或結束時,就緒隊列中的下一個進程佔用 CPU
。
實現簡單,但可能短進程排在長進程後面,致使平均等待時間波動較大。
短進程優先算法SJF
選擇就緒隊列中執行時間最短的進程佔用 CPU
運行。
短進程優先算法有最優的平均週轉時間,但連續的短進程可能會使長進程沒法得到 CPU
資源,致使飢餓;運行時間不可預估,並不可靠。
最高響應比優先算法HRN
選擇就緒隊列中響應比最高的進程。它是基於短進程優先算法的改進,它不容許搶佔,另外等待時間越長,響應比越高,能夠避免長時間地等待。
R = (w+s)/s // 其中 w 爲等待時間,s 爲執行時間。
複製代碼
時間片輪轉算法RR
按時間片分配給進程運行。在輪轉中,每一個進程分到執行 1/n
的時間,時間片結束時,按先來先服務算法切換到下一個就緒進程,每隔 n-1
個時間片進程會再次執行。
若是時間片過大,進程等待時間過長,極限狀況下會退化爲先來先服務算法;若是時間片太小,雖然反應迅速,但上下文切換開銷較大,會影響系統吞吐量。
多級反饋隊列算法
就緒隊列被劃分爲多個獨立的子隊列,並且每一個隊列能夠有本身的調度策略,在隊列之間能夠設置優先級,第一個隊列優先級最高,其他依次遞減。優先級越高的隊列分配的時間片越短。
在執行時,進程在不一樣隊列間移動,若是進程在當前優先級的時間片下沒有完成,則降低到低一優先級的隊列,以此類推。只有當一個隊列爲空時纔會去執行下一個隊列中的進程。
這種算法對於 CPU
密集型進程的優先級降低很快,而 I/O
密集型進程停留在高優先級。