大話javascript 4期:事件循環(1)

1、進程與線程

現代操做系統好比Mac OS X,UNIX,Linux,Windows等,都是支持「多任務」的操做系統。前端

什麼叫「多任務」呢?簡單地說,就是操做系統能夠同時運行多個任務。打個比方,你一邊在用瀏覽器上網,一邊在聽MP3,一邊在用Word趕做業,這就是多任務,至少同時有3個任務正在運行。還有不少任務悄悄地在後臺同時運行着,只是桌面上沒有顯示而已。ajax

如今,多核CPU已經很是普及了,可是,即便過去的單核CPU,也能夠執行多任務。因爲CPU執行代碼都是順序執行的,那麼,單核CPU是怎麼執行多任務的呢?瀏覽器

答案就是操做系統輪流讓各個任務交替執行,任務1執行0.01秒,切換到任務2,任務2執行0.01秒,再切換到任務3,執行0.01秒……這樣反覆執行下去。表面上看,每一個任務都是交替執行的,可是,因爲CPU的執行速度實在是太快了,咱們感受就像全部任務都在同時執行同樣。網絡

真正的並行執行多任務只能在多核CPU上實現,可是,因爲任務數量遠遠多於CPU的核心數量,因此,操做系統也會自動把不少任務輪流調度到每一個核心上執行。多線程

對於操做系統來講,一個任務就是一個進程(Process),好比打開一個瀏覽器就是啓動一個瀏覽器進程,打開一個記事本就啓動了一個記事本進程,打開兩個記事本就啓動了兩個記事本進程,打開一個Word就啓動了一個Word進程。異步

有些進程還不止同時幹一件事,好比Word,它能夠同時進行打字、拼寫檢查、打印等事情。在一個進程內部,要同時幹多件事,就須要同時運行多個「子任務」,咱們把進程內的這些「子任務」稱爲線程(Thread)佈局

因爲每一個進程至少要幹一件事,因此,一個進程至少有一個線程。固然,像Word這種複雜的進程能夠有多個線程,多個線程能夠同時執行,多線程的執行方式和多進程是同樣的,也是由操做系統在多個線程之間快速切換,讓每一個線程都短暫地交替運行,看起來就像同時執行同樣。固然,真正地同時執行多線程須要多核CPU纔可能實現。操作系統

若是咱們要同時執行多個任務怎麼辦?插件

有兩種解決方案:線程

一種是啓動多個進程,每一個進程雖然只有一個線程,但多個進程能夠一塊執行多個任務。

還有一種方法是啓動一個進程,在一個進程內啓動多個線程,這樣,多個線程也能夠一塊執行多個任務。

固然還有第三種方法,就是啓動多個進程,每一個進程再啓動多個線程,這樣同時執行的任務就更多了,固然這種模型更復雜,實際不多采用。

總結一下就是,多任務的實現有3種方式:

  1. 多進程模式;
  2. 多線程模式;
  3. 多進程+多線程模式。

同時執行多個任務一般各個任務之間並非沒有關聯的,而是須要相互通訊和協調,有時,任務1必須暫停等待任務2完成後才能繼續執行,有時,任務3和任務4又不能同時執行,因此,多進程和多線程的程序的複雜度要遠遠高於咱們前面寫的單進程單線程的程序。

由於複雜度高,調試困難,因此,不是無可奈何,咱們也不想編寫多任務。可是,有不少時候,沒有多任務還真不行。想一想在電腦上看電影,就必須由一個線程播放視頻,另外一個線程播放音頻,不然,單線程實現的話就只能先把視頻播放完再播放音頻,或者先把音頻播放完再播放視頻,這顯然是不行的。

總結:
1) 進程是cpu資源分配的最小單位(是能擁有資源和獨立運行的最小單位)
2) 線程是cpu調度的最小單位(線程是創建在進程的基礎上的一次程序運行單位,一個進程中能夠有多個線程)

2、瀏覽器是多進程的

瀏覽器包含哪些進程

1) Browser進程:瀏覽器的主進程(負責協調、主控),只有一個。做用有

  • 負責瀏覽器界面顯示,與用戶交互。如前進,後退等
  • 負責各個頁面的管理,建立和銷燬其餘進程
  • 將Renderer進程獲得的內存中的Bitmap,繪製到用戶界面上
  • 網絡資源的管理,下載等

2) 第三方插件進程:每種類型的插件對應一個進程,僅當使用該插件時才建立
3) GPU進程:最多一個,用於3D繪製等
4) 瀏覽器渲染進程(瀏覽器內核)(Renderer進程,內部是多線程的):默認每一個Tab頁面一個進程,互不影響。主要做用爲

  • 頁面渲染,腳本執行,事件處理等

關於瀏覽器進程問題能夠簡單基礎三點:

1) 瀏覽器是多進程的。
2) 瀏覽器之因此可以運行,是由於系統給它的進程分配了資源(cpu、內存)。
3) 簡單點理解,每打開一個Tab頁,就至關於建立了一個獨立的瀏覽器進程。

平時 coding 接觸到最多的一個瀏覽器進程是瀏覽器渲染進程(瀏覽器內核),它管理着頁面渲染。腳本執行,事件處理等。要同時處理這麼多事情,渲染進程顯然是多線程的,它主要包括如下5個常駐線程:

  1. GUI渲染線程,負責渲染瀏覽器界面,解析HTML,CSS,構建DOM樹和RenderObject樹,佈局和繪製等。
  2. JS引擎線程,也稱爲JS內核,負責處理Javascript腳本程序,(例如V8引擎)。
  3. 事件觸發線程,用來控制事件循環(能夠理解爲,JS引擎線程本身都忙不過來,須要瀏覽器另開線程協助)。
  4. 定時觸發器線程,瀏覽器定時計數器並非由JavaScript引擎計數的,(由於JavaScript引擎是單線程的, 若是處於阻塞線程狀態就會影響記計時的準確),JS中經常使用的setInterval和setTimeout就歸這個線程管理。
  5. 異步http請求線程,也就是ajax發出http請求後,接收響應、檢測狀態變動等都是這個線程管理的。

3、Javascript是單線程的

咱們常說的JavaScript是單線程的,其實就是說的JS引擎是單線程的,它僅僅是瀏覽器渲染進程種的一個線程。爲何呢?由於JavaScript的主要做用是與用戶互動,以及操做DOM,若是JavaScript有兩個線程,一個線程對一個DOM節點執行 A 操做,另外一個線程這個DOM節點執行 B 操做,那麼就會起衝突,因此JavaScript在前端的應用就註定了它是單線程的。

然而JavaScript的單線程特性就註定咱們不用它去完成密集的 cpu 運算,由於密集 cpu 運算耗時過長,阻塞頁面渲染。爲了解決這個問題,HTML5提出 Web Worker 標準,容許JavaScript腳本建立多個線程,可是子線程徹底受主線程控制,且不得操做DOM

若是你以爲這篇文章對你有所幫助,那就順便點個贊吧,點點關注不迷路~

黑芝麻哇,白芝麻發,黑芝麻白芝麻哇發哈!

前端哇發哈

相關文章
相關標籤/搜索