一、CPU
CPU是計算機的核心,其負責承擔計算機的計算任務。這里我們比喻為一個工廠。
二、進程
進程是一個具有一定獨立功能的程序在一個數據集上的一次動態執行的過程,是操作系統進行資源分配和調度的一個獨立單位,是應用程序運行的載體。
我們這里將進程比喻為工廠的車間,它代表CPU所能處理的單個任務。任一時刻,CPU總是運行一個進程,其他進程處於非運行狀態。
三、線程
線程是程序執行中一個單一的順序控制流程,是程序執行流的最小單元。
這里把線程比喻一個車間的工人,即一個車間可以允許由多個工人協同完成一個任務。
四、進程和線程的區別和關系
- 進程是操作系統分配資源的最小單位,線程是程序執行的最小單位。
- 一個進程由一個或多個線程組成,線程是一個進程中代碼的不同執行路線;
- 進程之間相互獨立,但同一進程下的各個線程之間共享程序的內存空間(包括代碼段、數據集、堆等)及一些進程級的資源(如打開文件和信號)。
- 調度和切換:線程上下文切換比進程上下文切換要
快得多
。
五、瀏覽器內核
瀏覽器內核是通過取得頁面內容、整理信息(應用CSS)、計算和組合最終輸出可視化的圖像結果,通常也被稱為渲染引擎。
Chrome瀏覽器為每個tab頁面單獨啟用進程,因此每個tab網頁都有由其獨立的渲染引擎實例。
在瀏覽器中打開一個網頁相當於新起了一個進程(進程內有自己的多線程)。
如果瀏覽器是單進程,那么某個Tab頁崩潰了,就影響了整個瀏覽器,體驗很差。同理如果是單進程,插件崩潰了也會影響整個瀏覽器。
六、瀏覽器的多線程
瀏覽器內核是多線程,在內核控制下各線程相互配合以保持同步,一個瀏覽器通常由以下常駐線程組成:
- GUI 渲染線程
- JavaScript引擎線程
- 事件觸發線程
- 定時觸發器線程
- 異步http請求線程
1.GUI渲染線程
GUI渲染線程
負責渲染瀏覽器界面HTML元素,解析HTML,CSS,構建DOM樹和RenderObject樹,布局和繪制等。
當界面需要重繪(Repaint)或由於某種操作引發回流(重排)(reflow)時,該線程就會執行。
在Javascript引擎運行腳本期間,GUI渲染線程都是處於掛起狀態的,也就是說被”凍結”了,GUI更新會被保存在一個隊列中等到JS引擎空閑時立即被執行。
2.JavaScript引擎線程
JavaScript引擎
,也可以稱為JS內核,主要負責處理Javascript腳本程序,例如V8引擎。
JS引擎一直等待着任務隊列中任務的到來,然后加以處理,一個Tab頁(renderer進程)中無論什么時候都只有一個JS線程在運行JS程序(單線程)。
注意⚠️:GUI渲染線程和JavaScript引擎線程互斥!
由於JavaScript是可操縱DOM的,如果在修改這些元素屬性同時渲染界面(即JavaScript線程和UI線程同時運行),那么渲染線程前后獲得的元素數據就可能不一致了。
因此為了防止渲染出現不可預期的結果,瀏覽器設置GUI渲染線程與JavaScript引擎為互斥的關系,當JavaScript引擎執行時GUI線程會被掛起,GUI更新會被保存在一個隊列中等到引擎線程空閑時立即被執行。
如果JS執行的時間過長,這樣就會造成頁面的渲染不連貫,導致頁面渲染加載阻塞的感覺。
3.事件觸發線程
當一個事件被觸發時該線程會把事件添加到待處理隊列的隊尾,等待JS引擎的處理。
這些事件可以是當前執行的代碼塊如定時任務、也可來自瀏覽器內核的其他線程如鼠標點擊、AJAX異步請求等,但由於JS的單線程關系所有這些事件都得排隊等待JS引擎處理。
4.定時觸發器線程
setInterval
與setTimeout
所在線程
瀏覽器定時計數器並不是由JavaScript引擎計數的, 因為JavaScript引擎是單線程的, 如果處於阻塞線程狀態就會影響記計時的准確。
通過單獨線程來計時並觸發定時(計時完畢后,添加到事件隊列中,等待JS引擎空閑后執行)
注意,W3C在HTML標准中規定,規定要求setTimeout中低於4ms的時間間隔算為4ms。
5.異步http請求線程
在XMLHttpRequest在連接后是通過瀏覽器新開一個線程請求。
將檢測到狀態變更時,如果設置有回調函數,異步線程就產生狀態變更事件,將這個回調再放入事件隊列中,再由JavaScript引擎執行。