進程與線程,單核與多核1. 簡介2. 程序3. 進程4. 線程5. 多進程與多線程的選擇6. 小結參考

1. 簡介

用戶打開瀏覽器,其實就是打開了瀏覽器應用程序。那麼什麼是程序呢?我們常說瀏覽器是多線程的,JS 是單線程的,那麼什麼是線程呢?說到線程,和我們常說的進程有什麼關係?這兩者和程序之間又是什麼關係呢? 爲了解答這些疑問,也爲了更好地理解瀏覽器的工作原理,我們有必要先學習一下程序,進程和線程的概念。另外我們還需要了解並行與併發以及多核與多機的概念。當然,我們只是簡單瞭解一下這些概念,如果想要深入研究,比如CPU的工作機制,需要向下看彙編與操作系統的知識,作爲淺析階段,這個系列肯定是不會涉及了。 js是單線程,如何實現異步?這種異步是不是併發?瀏覽器如何實現多線程開發?

2. 程序

2.1 程序的定義

程序描述計算機索要完成的具有獨立功能的,並在時間上按嚴格次序前後相繼的計算機操作序列的集合,是一個靜態的概念。

2.2 程序的執行

程序的執行可以分爲順序執行併發執行

2.2.1 順序執行

把一個具有獨立功能的程序獨佔處理機直到最終結束的過程稱爲順序執行。計算的CPU是通過時序脈衝來控制執行命令的。程序的順序執行有以下特點

  • 順序性 程序順序執行時,其執行過程可看作一系列嚴格按照程序規定的狀態轉移過程,也就是每執行一條指令,系統將從上一個執行狀態轉移到下一個執行狀態,且上一條指令的執行結束是下一條指令執行開始的充分條件。
  • 封閉性 程序執行的最終結果由給定的初始條件決定,不受外界因素影響。
  • 可再現性 程序執行的最終結果可再現。即,與執行速度無關,只有初始條件相同,則不論何時重複執行程序都會得到相同結果。
2.2.2 併發執行

程序的併發執行是爲增加計算系統的處理能力和提高資源利用率所採用的一種同時操作技術。

分爲兩種:一種是多道程序系統的程序執行環境變化所引起的多道程序的併發執行,(資源有限,資源的共享與競爭)多道程序的併發執行在宏觀上是同時進行的,但在微觀上(也就是執行級上)仍是順序執行(單核);一種是某道程序的幾個程序段中包含着一部分可以同時執行或順序顛倒執行的代碼。

程序的併發執行總結爲:一組在邏輯上互相獨立的程序或程序段在執行過程中,其執行時間在客觀上互相重疊。即,一個程序段的執行尚未結束,另一個程序段的執行已經開始的這種執行方式。

在許多情況下計算機需要能夠同時處理多個具有獨立功能的程序,其執行環境具有以下特點

  • 獨立性 邏輯上獨立,若資源充沛,每道程序都可以獨立執行,執行速度與其他程序無關,起止時間也獨立。
  • 隨機性 程序和數據的輸入和執行開始時間都是隨機的。
  • 資源共享性 即包括硬件也包括軟件。

程序併發執行的影響: 好處是充分地利用了系統資源,從而提高系統的處理能力;另一方面,由於資源共享和競爭,改變了程序的執行速度。一般情況下,併發執行的各程序段如果共享軟、硬件資源,都會造成其執行結果其執行速度影響的局面(封閉性和可再現性),爲了控制和協調各程序段執行過程中的軟、硬件資源的共享和競爭,必須應該有一個描述各程序段執行過程和共享資源的基本單位,即,進程

3. 進程

3.1 進程的定義

進程,是併發執行的程序在執行過程中分配和管理資源的基本單位,是一個動態概念,竟爭計算機系統資源的基本單位。每一個進程都有一個自己的地址空間,即進程空間。狹義上來理解,可以解釋爲正在運行的程序的實例(an instance of a computer program that is being executed)。

3.2 進程的特徵

進程有如下特徵:

  • 動態性 進程的實質是程序在多道程序系統中的一次執行過程,進程是動態產生,動態消亡的。
  • 併發性 任何進程都可以同其他進程一起併發執行。
  • 獨立性 進程是一個能獨立運行的基本單位,同時也是系統分配資源和調度的獨立單位。
  • 異步性 由於進程間的相互制約,使進程具有執行的間斷性,即進程按各自獨立的、不可預知的速度向前推進。
  • 結構特徵 進程由程序、數據和進程控制塊三部分組成。

3.3 進程的狀態

一個進程的生命週期可以劃分爲一組狀態,這些狀態刻畫了整個進程。進程狀態即體現一個進程的生命狀態,反映進程執行過程的變化。這些狀態隨着進程的執行和外界條件的變化而轉換。在三態模型中,進程狀態分爲三個基本狀態,即運行態,就緒態,阻塞態。在五態模型中,進程分爲新建態、終止態,運行態,就緒態,阻塞態。

3.3.1 三態模型

一個進程從創建而產生至撤銷而消亡的整個生命期間,有時佔有處理器執行,有時雖可運行但分不到處理器、有時雖有空閒處理器但因等待某個事件的發生而無法執行,這一切都說明進程和程序不相同,它是活動的且有狀態變化的,這可以用一組狀態加以刻畫。爲了便於管理進程,一般來說,按進程在執行過程中的不同情況至少要定義三種不同的進程狀態:

  1. 就緒(ready)態:進程具備運行條件,等待系統分配處理器以便運行。即進程已獲得除CPU外的所有必要資源,只等待CPU時的狀態。一個系統會將多個處於就緒狀態的進程排成一個就緒隊列。
  2. 運行(running)態:又譯作執行態。進程佔有處理器正在運行。即進程已獲CPU,正在執行。單處理機系統中,處於執行狀態的進程只一個;多處理機系統中,有多個處於執行狀態的進程。
  3. 等待(wait)態:又稱爲阻塞(blocked)態或睡眠(sleep)態,指進程不具備運行條件,正在等待某個事件的完成。即正在執行的進程由於某種原因而暫時無法繼續執行,便放棄處理機而處於暫停狀態,即進程執行受阻。

通常,一個進程在創建後將處於就緒狀態。每個進程在執行過程中,任意時刻當且僅當處於上述三種狀態之一。同時,在一個進程執行過程中,它的狀態將會發生改變。引起進程狀態轉換的具體原因如下:

  1. 運行態——等待態:等待使用資源或某事件發生,如等待外設傳輸,等待人工干預。
  2. 等待態——就緒態:資源得到滿足或某事件己經發生,如外設傳輸結束,人工干預完成。
  3. 運行態——就緒態:運行時間片到,或出現有更高優先權進程。
  4. 就緒態——運行態:CPU空閒時被調度選中一個就緒進程執行。

三態的轉換可以看以下兩張圖,意思其實是一樣的:

三態轉換1

三態轉換2

3.3.2 五態模型

在一個實際的系統裏進程的狀態及其轉換比上節敘述的複雜一些,例如,引入專門的新建態(new)和終止態(exit )。

  1. 新建(new)態:又譯作創建態。新建態對應於進程剛剛被創建的狀態,創建一個進程要通過兩個步驟,首先,是爲一個新進程創建PCB,並填寫必要管理信息;然後,讓該進程進入就緒態。此時進程將處於新建態,它並沒有被提交執行,而是在等待操作系統完成創建進程的必要操作。必須指出的是,操作系統有時將根據系統性能或主存容量的限制推遲新建態進程的提交。
  2. 終止(exit)態:進程的終止也要通過兩個步驟,首先,是等待操作系統進行善後;然後,退出主存。當一個進程到達了自然結束點,或是出現了無法克服的錯誤,或是被操作系統所終結,或是被其他有終止權的進程所終結,它將進入終止態。進入終止態的進程以後不再執行,但依然保留在操作系統中等待善後。一旦其他進程完成了對終止態進程的信息抽取之後,操作系統將刪除該進程。

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

  1. NULL——新建態: 執行一個程序,創建一個子進程。
  2. 新建態——就緒態: 當操作系統完成了進程創建的必要操作,並且當前系統的性能和內存的容量均允許。
  3. 運行態——終止態: 當一個進程到達了自然結束點,或是出現了無法克服的錯誤,或是被操作系統所終結,或是被其他有終止權的進程所終結。
  4. 終止態——NULL: 完成善後操作。
  5. 就緒態——終止態: 未在狀態轉換圖中顯示,但某些操作系統允許父進程終結子進程。
  6. 等待態——終止態: 未在狀態轉換圖中顯示,但某些操作系統允許父進程終結子進程。

五態的轉換可以看下面這張圖:

五態轉換

3.3.3 狀態控制
  1. 進程創建 每個進程都有生命期,即從創建到消亡的時間週期。當操作系統爲一個程序構造一個進程控制塊並分配地址空間之後,就創建了一個進程。進程的創建來源於以下四個事件: (1)提交個批處理作業。 (2)在終端上個交互式作業登錄。 (3)操作系統創建‘個服務進程。 (4)存在的進程創建新的進程。
  2. 進程的阻塞和喚醒 進程的阻塞是指使一個進程讓出處理器,去等待一個事件,如等待資源、等待I/O完成、等待一個事件發生等,通常進程自己調用阻塞原語阻塞自己,所以,是進程自主行爲,是一個同步事件。當一個等待事件結束會產生一箇中斷,從而,激活操作系統,在系統的控制之下將被阻塞的進程喚醒,如I/O操作結束、某個資源可用或期待事件出現。進程的阻塞和喚醒顯然是由進程切換來完成。
  3. 進程的撤銷 一個進程完成了特定的工作或出現了嚴重的異常後,操作系統則收回它佔有的地址空間和進程控制塊,此時就說撤銷了一個進程。進程撤銷可以分正常和非正常撤銷,前者如分時系統中的注消和批處理系統中的撤離作業步,後者如進程運行過程中出現錯誤與異常。
  4. 進程的掛起和激活 當出現了引起掛起的事件時系統或進程利用掛起原語把指定進程或處於阻塞狀態的進程掛起。其執行過程大致如下:檢查要被掛起進程的狀態,若處於活動就緒態就修改爲掛起就緒,若處於阻塞態,則修改爲掛起阻塞。被掛起進程PCB的非常駐部分要交換到磁盤對換區。 當系統資源尤其是內存資源充裕或進程請求激活指定進程時,系統或有關進程會調用激活原語把指定進程激活,該原語所做的主要工作是:把進程PCB非常駐部分調進內存,然後修改它的狀態,掛起等待態改爲等待態,掛起就緒態改爲就緒態,並分別排入相應隊列中。

可以參考下圖:

3.4 進程和程序的區別和聯繫:

  1. 進程是一個動態概念,而程序是一個靜態的概念。程序是指令的有序集合,沒有任何執行的意義,而進程則強調執行過程,它動態被創建,並被調度執行消亡。
  2. 進程具有併發特點。進程具有併發特徵的兩個方面:獨立性和異步性——不考慮資源的情況下,各進程的執行是獨立的,速度是異步的,而程序沒有併發特徵。
  3. 進程是競爭計算系統資源的基本單位,從而其併發性受到系統自己的制約,這裏,制約就是對程序獨立性和異步性的限制。
  4. 一個程序可對應多個進程,也就是說同一程序同時運行於若干個數據集合上,它屬於若干個不同的進程。但是程序並不能獨立運行,作爲資源分配和獨立運行的基本單元都是進程。 一個進程可以對應多個程序。

一個更有意思的解釋可以參考這篇文章:進程和程序(Process and Program)

4. 線程

4.1 線程的定義

線程的出現是爲了降低上下文切換的消耗,提高系統的併發性,並突破一個進程只能幹一樣事的缺陷,使到進程內併發成爲可能。

假設,一個文本程序,需要接受鍵盤輸入,將內容顯示在屏幕上,還需要保存信息到硬盤中。若只有一個進程,勢必造成同一時間只能幹一樣事的尷尬(當保存時,就不能通過鍵盤輸入內容)。若有多個進程,每個進程負責一個任務,進程A負責接收鍵盤輸入的任務,進程B負責將內容顯示在屏幕上的任務,進程C負責保存內容到硬盤中的任務。這裏進程A,B,C間的協作涉及到了進程通信問題,而且有共同都需要擁有的東西——-文本內容,不停的切換造成性能上的損失。若有一種機制,可以使任務A,B,C共享資源,這樣上下文切換所需要保存和恢復的內容就少了,同時又可以減少通信所帶來的性能損耗,那就好了。是的,這種機制就是線程。

線程也叫輕量級進程,它是一個基本的CPU執行單元,也是程序執行過程中的最小單元,由線程ID、程序計數器、寄存器集合和堆棧共同組成。線程的引入減小了程序併發執行時的開銷,提高了操作系統的併發性能。線程沒有自己的系統資源,只擁有一點兒在運行中必不可少的資源,但它可與同屬一個進程的其它線程共享進程所擁有的全部資源。一個線程可以創建和撤消另一個線程,同一進程中的多個線程之間可以併發執行。

4.2 線程的特徵

在多線程OS中,通常是在一個進程中包括多個線程,每個線程都是作爲利用CPU的基本單位,是花費最小開銷的實體。線程具有以下屬性。

  1. 輕型實體 線程中的實體基本上不擁有系統資源,只是有一點必不可少的、能保證獨立運行的資源。 線程的實體包括程序、數據和TCB。線程是動態概念,它的動態特性由線程控制塊TCB(Thread Control Block)描述。TCB包括以下信息: (1)線程狀態。 (2)當線程不運行時,被保存的現場資源。 (3)一組執行堆棧。 (4)存放每個線程的局部變量主存區。 (5)訪問同一個進程中的主存和其它資源。 用於指示被執行指令序列的程序計數器、保留局部變量、少數狀態參數和返回地址等的一組寄存器和堆棧。
  2. 獨立調度和分派的基本單位 在多線程OS中,線程是能獨立運行的基本單位,因而也是獨立調度和分派的基本單位。由於線程很“輕”,故線程的切換非常迅速且開銷小(在同一進程中的)。
  3. 可併發執行 在一個進程中的多個線程之間,可以併發執行,甚至允許在一個進程中所有線程都能併發執行;同樣,不同進程中的線程也能併發執行,充分利用和發揮了處理機與外圍設備並行工作的能力。
  4. 共享進程資源 在同一進程中的各個線程,都可以共享該進程所擁有的資源,這首先表現在:所有線程都具有相同的地址空間(進程的地址空間),這意味着,線程可以訪問該地址空間的每一個虛地址;此外,還可以訪問進程所擁有的已打開文件、定時器、信號量機構等。由於同一個進程內的線程共享內存和文件,所以線程之間互相通信不必調用內核。

4.3 線程的狀態

線程從創建、運行到結束總是處於下面五個狀態之一:新建狀態、就緒狀態、運行狀態、阻塞狀態及死亡狀態。

  1. 新建狀態(New Thread) 產生一個Thread對象就生成一個新線程。當線程處於"新線程"狀態時,僅僅是一個空線程對象,它還沒有分配到系統資源。因此只能啓動或終止它。任何其他操作都會引發異常。例如,一個線程調用了new方法之後,並在調用start方法之前的處於新線程狀態,可以調用start和stop方法。
  2. 就緒狀態(Runnable) start()方法產生運行線程所必須的資源,調度線程執行,並且調用線程的run()方法。在這時線程處於就緒狀態。該狀態不稱爲運行態是因爲這時的線程並不總是一直佔用處理機。特別是對於只有一個處理機的PC而言,任何時刻只能有一個處於就緒態的線程佔用處理機。Java通過調度來實現多線程對處理機的共享。注意,如果線程處於Runnable狀態,它也有可能不在運行,這是因爲還有優先級和調度問題。
  3. 運行狀態(Running) 當線程獲得CPU時間後,它才進入運行狀態,真正開始執行run()方法。
  4. 阻塞狀態(Blocked) 所謂阻塞狀態是正在運行的線程沒有運行結束,暫時讓出CPU,這時其他處於就緒狀態的線程就可以獲得CPU時間,進入運行狀態。 阻塞狀態分爲三種: 1、等待阻塞:運行的線程執行wait()方法,JVM會把該線程放入等待池中。 2、同步阻塞:運行的線程在獲取對象同步鎖時,若該同步鎖被別的線程佔用,則JVM會把線程放入鎖池中。 3、其他阻塞:運行的線程執行Sleep()方法,或者發出I/O請求時,JVM會把線程設爲阻塞狀態。當Sleep()狀態超時、或者I/O處理完畢時,線程重新轉入就緒狀態。 線程運行過程中,可能由於各種原因進入阻塞狀態: ①線程通過調用sleep方法進入睡眠狀態; ②線程調用一個在I/O上被阻塞的操作,即該操作在輸入輸出操作完成之前不會返回到它的調用者; ③線程試圖得到一個鎖,而該鎖正被其他線程持有; ④線程在等待某個觸發條件; 具體來講,線程被堵塞可能是由下述五個方法造成的: (1) 調用sleep(毫秒數),使線程進入"睡眠"狀態。在規定的時間內,這個線程是不會運行的。 (2) 用suspend()暫停了線程的執行。除非線程收到resume()消息,否則不會返回"可運行"狀態。 (3) 用wait()暫停了線程的執行。除非線程收到nofify()或者notifyAll()消息,否則不會變成"可運行"(是的,這看起來同原因2非常相象,但有一個明顯的區別是我們馬上要揭示的)。 (4) 線程正在等候一些IO(輸入輸出)操作完成。 (5) 線程試圖調用另一個對象的"同步"方法,但那個對象處於鎖定狀態,暫時無法使用。
  5. 死亡狀態(Dead) 當線程執行完run()方法中的代碼,或別的線程調用stop()方法,或者遇到了未捕獲的異常,就會退出run()方法,此時就進入死亡狀態,該線程結束生命週期。通常Applet使用它的stop()方法來終止它產生的所有線程。 爲了確定線程在當前是否存活着(就是要麼是可運行的,要麼是被阻塞了),需要使用isAlive方法,如果是可運行或被阻塞,這個方法返回true;如果線程仍舊是new狀態且不是可運行的,或者線程死亡了,則返回false。

可以參考下圖:

線程狀態

詳細地狀態轉換可以參考這裏線程的幾種狀態轉換

4.4 線程和進程的關係和區別

進程和線程的關係: (1)一個線程只能屬於一個進程,而一個進程可以有多個線程,至少有一個線程。 (2)資源分配給進程,同一進程的所有線程共享該進程的所有資源。 (3)處理機分給線程,即真正在處理機上運行的是線程。 (4)線程在執行過程中,需要協作同步。不同進程的線程間要利用消息通信的辦法實現同步。線程是指進程內的一個執行單元,也是進程內的可調度實體.

進程與線程的區別: (1)調度:線程作爲調度和分配的基本單位,進程作爲擁有資源的基本單位 (2)併發性:不僅進程之間可以併發執行,同一個進程的多個線程之間也可併發執行 (3)擁有資源:進程是擁有資源的一個獨立單位,線程不擁有系統資源,但可以訪問隸屬於進程的資源. (4)系統開銷:在創建或撤消進程時,由於系統都要爲之分配和回收資源,導致系統的開銷明顯大於創建或撤消線程時的開銷。

5. 多進程與多線程的選擇

5.1並行與併發

併發處理(concurrency Processing):指一個時間段中有幾個程序都處於已啓動運行到運行完畢之間,且這幾個程序都是在同一個處理機(CPU)上運行,但任一個時刻點上只有一個程序在處理機(CPU)上運行。當有多個線程在操作時,如果系統只有一個CPU,則它根本不可能真正同時進行一個以上的線程,它只能把CPU運行時間劃分成若干個時間段,再將時間 段分配給各個線程執行,在一個時間段的線程代碼運行時,其它線程處於掛起狀。這種方式我們稱之爲併發(Concurrent)。

並行:當系統有一個以上CPU時,則線程的操作有可能非併發。當一個CPU執行一個線程時,另一個CPU可以執行另一個線程,兩個線程互不搶佔CPU資源,可以同時進行,這種方式我們稱之爲並行(Parallel)。並行處理(Parallel Processing)是計算機系統中能同時執行兩個或更多個處理的一種計算方法。並行處理可同時工作於同一程序的不同方面。並行處理的主要目的是節省大型和複雜問題的解決時間。

併發的關鍵是你有處理多個任務的能力,不一定要同時。並行的關鍵是你有同時處理多個任務的能力。所以說,並行是併發的子集。

串行,並行,併發

5.2 多核與多機

  • 多處理機(SMP):
  1. 多個物理cpu
  2. 每個cpu有自己的獨立cache、寄存器、運算單元。
  3. 每個cpu對內存的訪問速度一樣。
  • 多核cpu (雙核)
  1. 一個物理cpu包含多個cpu核心。
  2. 每個核心有自己的獨立寄存器和運算單元。
  3. 可共享最後一級cache。
  • 多線程cpu (雙核四線程)
  1. 一個物理cpu包含多個邏輯cpu;這些邏輯cpu有自己的通用寄存器。
  2. 共享cache和運算單元(邏輯cpu)。
  3. 由於cpu通常包含多個運算單元,因此多線程cpu實際可同時運行。

5.3 多進程與多線程

5.3.1 多進程與多線程的優勢對比

多進程與多線程的對比

5.3.2進程之間,線程之間的通信方式以及優缺點

進程之間的通信: 1)管道 管道分爲有名管道和無名管道 無名管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有親緣關係的進程間使用.進程的親緣關係一般指的是父子關係。無明管道一般用於兩個不同進程之間的通信。當一個進程創建了一個管道,並調用fork創建自己的一個子進程後,父進程關閉讀管道端,子進程關閉寫管道端,這樣提供了兩個進程之間數據流動的一種方式。 有名管道也是一種半雙工的通信方式,但是它允許無親緣關係進程間的通信。

無名管道: 優點:簡單方便; 缺點:1)侷限於單向通信2)只能創建在它的進程以及其有親緣關係的進程之間;3)緩衝區有限; 有名管道: 優點:可以實現任意關係的進程間的通信; 缺點:1)長期存於系統中,使用不當容易出錯;2)緩衝區有限

2)信號量 信號量是一個計數器,可以用來控制多個線程對共享資源的訪問.,它不是用於交換大批數據,而用於多線程之間的同步.它常作爲一種鎖機制,防止某進程在訪問資源時其它進程也訪問該資源.因此,主要作爲進程間以及同一個進程內不同線程之間的同步手段.

優點:可以同步進程; 缺點:信號量有限

3)信號 信號是一種比較複雜的通信方式,用於通知接收進程某個事件已經發生.

4)消息隊列 消息隊列是消息的鏈表,存放在內核中並由消息隊列標識符標識.消息隊列克服了信號傳遞信息少,管道只能承載無格式字節流以及緩衝區大小受限等特點.消息隊列是UNIX下不同進程之間可實現共享資源的一種機制,UNIX允許不同進程將格式化的數據流以消息隊列形式發送給任意進程.對消息隊列具有操作權限的進程都可以使用msget完成對消息隊列的操作控制.通過使用消息類型,進程可以按任何順序讀信息,或爲消息安排優先級順序.

優點:可以實現任意進程間的通信,並通過系統調用函數來實現消息發送和接收之間的同步,無需考慮同步問題,方便; 缺點:信息的複製需要額外消耗CPU的時間,不適宜於信息量大或操作頻繁的場合

5)共享內存 共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問.共享內存是最快的IPC(進程間通信)方式,它是針對其它進程間通信方式運行效率低而專門設計的.它往往與其他通信機制,如信號量,配合使用,來實現進程間的同步與通信.

優點:無須複製,快捷,信息量大; 缺點:1)通信是通過將共無法實現享空間緩衝區直接附加到進程的虛擬地址空間中來實現的,因此進程間的讀寫操作的同步問題;2)利用內存緩衝區直接交換信息,內存的實體存在於計算機中,只能同一個計算機系統中的諸多進程共享,不方便網絡通信

6)套接字:可用於不同及其間的進程通信 優點:1)傳輸數據爲字節級,傳輸數據可自定義,數據量小效率高;2)傳輸數據時間短,性能高;3) 適合於客戶端和服務器端之間信息實時交互;4) 可以加密,數據安全性強 缺點:1) 需對傳輸的數據進行解析,轉化成應用級的數據。

線程之間的通信方式:

  • 鎖機制:包括互斥鎖、條件變量、讀寫鎖
    • 互斥鎖提供了以排他方式防止數據結構被併發修改的方法。
    • 讀寫鎖允許多個線程同時讀共享數據,而對寫操作是互斥的。
    • 條件變量可以以原子的方式阻塞進程,直到某個特定條件爲真爲止。對條件的測試是在互斥鎖的保護下進行的。條件變量始終與互斥鎖一起使用。
  • 信號量機制(Semaphore):包括無名線程信號量和命名線程信號量
  • 信號機制(Signal):類似進程間的信號處理

線程間的通信目的主要是用於線程同步,所以線程沒有像進程通信中的用於數據交換的通信機制。

5.3.3 多進程與多線程的選擇
  1. 需要頻繁創建銷燬的優先用線程 原因請看上面的對比。 這種原則最常見的應用就是Web服務器了,來一個連接建立一個線程,斷了就銷燬線程,要是用進程,創建和銷燬的代價是很難承受的
  2. 需要進行大量計算的優先使用線程 所謂大量計算,當然就是要耗費很多CPU,切換頻繁了,這種情況下線程是最合適的。 這種原則最常見的是圖像處理、算法處理。
  3. 強相關的處理用線程,弱相關的處理用進程 什麼叫強相關、弱相關?理論上很難定義,給個簡單的例子就明白了。 一般的Server需要完成如下任務:消息收發、消息處理。“消息收發”和“消息處理”就是弱相關的任務,而“消息處理”裏面可能又分爲“消息解碼”、“業務處理”,這兩個任務相對來說相關性就要強多了。因此“消息收發”和“消息處理”可以分進程設計,“消息解碼”、“業務處理”可以分線程設計。 當然這種劃分方式不是一成不變的,也可以根據實際情況進行調整。
  4. 可能要擴展到多機分佈的用進程,多核分佈的用線程 原因請看上面對比。
  5. 都滿足需求的情況下,用你最熟悉、最拿手的方式 至於“數據共享、同步”、“編程、調試”、“可靠性”這幾個維度的所謂的“複雜、簡單”應該怎麼取捨,我只能說:沒有明確的選擇方法。但我可以告訴你一個選擇原則:如果多進程和多線程都能夠滿足要求,那麼選擇你最熟悉、最拿手的那個。

需要提醒的是:雖然有如此多選擇與比較原則,但實際應用中基本上都是“進程+線程”的結合方式,千萬不要真的陷入一種非此即彼的誤區。

6. 小結

以上這些知識,其實是爲了我們後續的講解做鋪墊,如果大家覺得很繁冗。可以歸直接記住以下幾點:

  1. 瀏覽器本身是一個程序,當我們運行它,操作學習通就開啓了瀏覽器相關的進程。
  2. 瀏覽器進程裏面包含了若干的線程。
  3. 一個核心同一時間只能處理一個線程,不過可以通過時間分片來實現多任務的併發,多核可以達成真正意義的並行。另外超線程技術通過邏輯CPU模擬核心達到並行,但是實際能力會弱於多核。

當然,作爲一個前端開發者,你並不需要關心,你的線程會被分配給哪一個核心處理,這個會由操作系統根據一定算法進行調度。這些內容是爲了下一階段知識做鋪墊而已,理解了這些,我們才能去探索爲何我們說js是單線程的,但是卻可以實現異步,在處理邏輯的時候還能進行請求操作等現象背後的原因。

參考

進程的概念 進程狀態-百度百科 進程三種基本狀態 進程五種基本狀態 程序、進程和線程的關係 線程-百度百科 進程-百度百科 多線程—線程的5種狀態 線程的基本概念、線程的基本狀態以及狀態之間的關係 多線程與多進程 進程與線程的區別-百度經驗 進程和線程的區別以及聯繫 基礎知識:線程,進程。多進程,多線程。併發,並行的區別 多處理機、多核cpu、多線程cpu的區別 多線程還是多進程的選擇及區別 進程線程面試題總結

線程和進程的區別是什麼? 進程上下文和中斷上下文 多進程和多線程的優缺點 進程與線程的一個簡單解釋 深入理解javascript異步編程障眼法&&h5 web worker實現多線程 淺談多核CPU、多線程與並行計算 處理器關於多核概念與區別 多核處理器工作原理及優缺點 對於多線程程序,單核cpu與多核cpu是怎麼工作的 cpu個數、核數、線程數、Java多線程關係的理解 單核處理器、多核處理器、多處理器與多線程編程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章