最近在看瀏覽器多進程,JS單線程、瀏覽器渲染機制等相關知識,(原文:掘金-從瀏覽器多進程到JS單線程,JS運行機制最全面的一次梳理)覺得還是有必要總結下並行與並發、進程與線程這些知識點。文章大部分來源於《計算機操作系統 第四版》,大學的課本,現在翻翻,太香了。看了網上那么多解釋后,還是書上系統的內容更容易接受。
內容速覽
進程和並發是現代操作系統中最重要的基本概念,也是操作系統運行的基礎。
並發性是指兩個或多個事件在同一時間間隔內發生。(個人覺得強調的是有多個事件同時存在)
並行是指兩個或多個事件在同一時刻發生。(個人覺得強調的是多個事件同時發生,當有多個處理機的時候能實現)
進程是cpu資源分配的最小單位(是能擁有資源和獨立運行的最小單位)
線程是cpu調度的最小單位(線程是建立在進程的基礎上的一次程序運行單位,一個進程中可以有多個線程)
並發與並行
並發是操作系統的一個基本特性,使得OS能有效地提高系統中的資源利用率,增加系統的吞吐量。
並發性是指兩個或多個事件在同一時間間隔內發生。(個人覺得強調的是有多個事件同時存在)
並行是指兩個或多個事件在同一時刻發生。(個人覺得強調的是多個事件同時發生)
倘若在計算機系統中有多個處理機,那些可以並發執行的程序(即不存在前趨關系)便可被分配到多個處理機上,實現並行執行,即利用每個處理機來處理一個可並發執行的程序。這樣,多個程序便可同時執行。(這里埋個點:程序與進程的關系作為進程的下文引入)
在多道程序環境下,並發性是指在一段時間內宏觀上有多個程序在同時運行。但是在單處理機系統中,每一時刻只能有一道程序執行,故微觀上這些程序只能是分時地交替運行。(這里涉及到的單道批處理系統和多道批處理系統,建議去看看計算機操作系統的發展過程)
進程與線程
推薦博文:阮一峰 進程與線程的一個解釋,一個超級形象的圖示版,淺顯易懂非常推薦。我想更深入了解,還是放了操作系統中進程的概念:
在20世紀60年代中期,人們在設計多道程序OS時,引入了進程的概念,從而解決了在單處理機環境下的程序並發執行問題。之后在長達20年的時間里,在多道程序OS中一直是以進程作為能擁有資源和獨立調度(運行)的基本單位的。直到80年代中期,人們又提出了比進程更小的基本單位——線程,試圖用它來提高程序並發執行的程度,以進一步改善系統的服務質量。
本質上來說,兩個名詞都是 CPU 工作時間片的一個描述。進程描述了 CPU 在運行指令及加載和保存上下文所需的時間,放在應用上來說就代表了一個程序。線程是進程中的更小單位,描述了執行一段指令所需的時間。
進程
在多道程序環境下,程序的執行屬於並發執行,此時他們將失去其封閉性,並具有間斷性,以及其運行結果不可再現性的特征。由此,決定了通常的程序是不能參與並發執行的,否則,程序的運行也就失去了意義。為了能使程序並發執行,並且可以對並發執行的程序加以描述和控制,人們引入了“進程”的概念。
為了使參與並發執行的每個進程(含數據)都能獨立地運行,在操作系統中必須為之配置一個專門的數據結構,稱為進程控制塊(PCB)。系統利用PCB來描述進程的基本情況和活動過程,進而控制和管理進程。這樣,由程序段、相關的數據段和PCB三部分便構成了進程實體(又稱進程映像)。所謂創建和撤銷進程,實質上是創建和撤銷進程中的PCB。
所謂進程,它由一組機器指令、數據和堆棧等組成的,是一個能獨立運行的活動實體。
1)典型定義:
-
進程是程序的一次執行
-
進程是一個程序及其數據在處理機上順序執行時所發生的活動
-
進程是具有獨立功能的程序在一個數據集合上運行的過程,是系統進行資源分配和調度的一個獨立單位。
在引入進程實體的概念后,我們可以把傳統OS中的進程定義為:進程是進程實體的運行過程,是系統進行資源分配和調度的一個獨立單位。
2)進程的兩個基本屬性
-
進程是一個可擁有資源的獨立單位,一個進程要能獨立運行,它必須有一定的資源,包括用於存放程序正文、數據的磁盤和內存地址空間,以及它在運行時所需要的I/O設備、已打開的文件、信號量等;
-
進程是一個可獨立調度和分派的基本單位,保證了其獨立運行。每個進程在系統中有唯一的PCB,系統可根據其PCB感知進程的存在,也可根據其PCB中的信息,對進程進行調度,還可將斷點信息保存在其PCB中。反之,再利用進程PCB中的信息來回復進程運行的現場。
正是由於進程有這兩個基本屬性,才能使進程成為一個獨立運行的基本單位,從而也就構成了進程並發執行的基礎。
3)為使程序能並發執行,系統必須進行一下的一系列操作:
-
創建進程,系統在床架一個進程時,必須為它分配其所必須的、除處理機以外的所有資源,如內存空間、I/O設備,以及建立相應的PCB
-
撤銷進程,系統在撤銷進程時,又必須先對其所占有的資源執行回收操作,然后再撤銷PCB
-
進程切換,對進程進行上下文切換時,需要保留當前進程的CPU環境,設置新選中進程的CPU環境,因而花費不少的處理機時間。
據此可知,由於進程是一個資源的擁有者,因而在創建、撤銷和切換中,系統必須為之付出較大的時空開銷。這就限制了系統中所設置進程的數目,而進程切換也不宜過於頻繁,從而限制了並發程度的進一步提高。那么,如何能使多個程序更好地並發執行,同時又能盡量減少系統的開銷?那就需要設法將進程的上述兩個屬性分開,由OS分開處理,即並不把作為調度和分派的基本單位也同時作為擁有資源的單位,以做到“輕裝上陣”;而對於擁有資源的基本單位,又不對之施以頻繁的切換。於是,引入了線程
線程
1)調度的基本單位
在引入線程的OS中,已把線程作為調度和分配的基本單位,因而線程是能獨立運行的基本單位(注意,脫離了進程的線程談這句話就是耍流氓)。當線程切換時,僅需保存和設置少量寄存器內容,切換代價遠低於進程。
牛客原題:線程是比進程更小的能獨立運行的基本單位,這樣的說法正確嗎? ✖(線程必須依附在進程里,由進程申請cpu才能運行)
2)並發性
一個進程中的多個甚至所有線程之間都可並發執行,使得OS具有更好的並發性。例如,在文字處理器中可以設置三個線程:1.顯示文字和圖形,2.從鍵盤讀入數據,3.在后台進行拼寫和語法檢查。又如在網頁瀏覽器中,可以設置一個線程來顯示圖像或文本,再設置一個線程用於從網絡中接收數據。
此外,有的應用程序需要執行多個相似的任務,例如:一個網絡服務器經常會接收到許多客戶的請求,如果人采用傳統的單線程的進程來執行該任務,則每次只能為一個客戶服務。但如果在一個進程中可以設置多個線程,將其中一個專用於監聽客戶的請求,則每當有一個客戶請求時,便立即創建一個線程來處理該客戶的請求。
3)擁有資源
注意,線程系統中一個可擁有資源的基本單位。但並不擁有系統資源,而是僅有一點必不可少的、能保證獨立運行的資源。比如,在每個線程中都應具有一個用於控制線程運行的線程控制塊TCB、用於指示被執行指令序列的程序計數器、保留局部變量、少量狀態參數和返回地址等的一組寄存器和堆棧。
線程除了擁有自己的少數資源外,還允許多個線程共享該進程鎖擁有的資源。表現在:屬於同一進程的所有線程都具有相同的地址空間,這意味着,線程可以訪問該地址空間中的每一個虛地址;此外,還可以訪問進程所擁有的資源,如它申請到的I/O設備等。一個線程的堆棧可以被其它線程讀寫,甚至完全清除。由一個線程打開的文件可以供其它線程讀、寫。
4)系統開銷
在創建或撤銷進程時,系統都要為之分配和回收進程控制塊、分配或回收其它資源,如內存空間和I/O設備等。OS為此所付出的開銷,明顯大於線程創建或撤銷時所付出的開銷。類似的,在進程切換時,涉及到進程上下文的切換,而線程的切換代價也遠低於進程的。此外,由於屬於同一進程的所有線程都具有相同的地址空間,線程之間的同步和通信也比進程的簡單。