CPU
CPU是計算機的核心贯涎,其負(fù)責(zé)承擔(dān)計算機的計算任務(wù)。這里我們比喻為一個工廠
進(jìn)程(process)
- 簡單理解陆盘,進(jìn)程就是程序的一次執(zhí)行败明。
- 進(jìn)程是任務(wù)調(diào)度的最小單位妻顶,每個進(jìn)程有各自獨立的一塊內(nèi)存,使得各個進(jìn)程之間內(nèi)存地址相互隔離沸呐。
- 我們這里將進(jìn)程比喻為工廠的車間呢燥,它代表CPU所能處理的單個任務(wù)寓娩。任一時刻,CPU總是運行一個進(jìn)程寞埠,其他進(jìn)程處于非運行狀態(tài)焊夸。
線程(thread)
線程,有時被稱為輕量進(jìn)程(Lightweight Process饭冬,LWP)揪阶,是程序執(zhí)行流的最小單元鲁僚。這里把線程比喻一個車間的工人裁厅,即一個車間可以允許由多個工人協(xié)同完成一個任務(wù)侨艾。
進(jìn)程和線程的區(qū)別和關(guān)系
- 進(jìn)程是操作系統(tǒng)分配資源的最小單位,線程是程序執(zhí)行的最小單位袋励。
- 一個進(jìn)程由一個或多個線程組成姻成,線程是一個進(jìn)程中代碼的不同執(zhí)行路線科展;
- 進(jìn)程之間相互獨立,但同一進(jìn)程下的各個線程之間共享程序的內(nèi)存空間(包括代碼段徘跪、數(shù)據(jù)集琅攘、堆等)及一些進(jìn)程級的資源(如打開文件和信號)。
- 調(diào)度和切換:線程上下文切換比進(jìn)程上下文切換要快得多哨查。
多進(jìn)程和多線程
- 多進(jìn)程:多進(jìn)程指的是在同一個時間里剧辐,同一個計算機系統(tǒng)中如果允許兩個或兩個以上的進(jìn)程處于運行狀態(tài)荧关。多進(jìn)程帶來的好處是明顯的,比如你可以聽歌的同時加勤,打開編輯器敲代碼同波,編輯器和聽歌軟件的進(jìn)程之間絲毫不會相互干擾。
- 多線程是指程序中包含多個執(zhí)行流卫枝,即在一個程序中可以同時運行多個不同的線程來執(zhí)行不同的任務(wù)讹挎,也就是說允許單個程序創(chuàng)建多個并行執(zhí)行的線程來完成各自的任務(wù)吆玖。
瀏覽器多進(jìn)程架構(gòu)
跟現(xiàn)在的很多多線程瀏覽器不一樣沾乘,Chrome瀏覽器使用多個進(jìn)程來隔離不同的網(wǎng)頁浑测。因此在Chrome中打開一個網(wǎng)頁相當(dāng)于起了一個進(jìn)程。
那么Chrome為什么要使用多進(jìn)程架構(gòu)?
在瀏覽器剛被設(shè)計出來的時候掷匠,那時的網(wǎng)頁非常的簡單岖圈,每個網(wǎng)頁的資源占有率是非常低的,因此一個進(jìn)程處理多個網(wǎng)頁時可行的蜂科。然后在今天导匣,大量網(wǎng)頁變得日益復(fù)雜。把所有網(wǎng)頁都放進(jìn)一個進(jìn)程的瀏覽器面臨在健壯性赋访,響應(yīng)速度缓待,安全性方面的挑戰(zhàn)。因為如果瀏覽器中的一個tab網(wǎng)頁崩潰的話,將會導(dǎo)致其他被打開的網(wǎng)頁應(yīng)用国葬。另外相對于線程芹壕,進(jìn)程之間是不共享資源和地址空間的,所以不會存在太多的安全問題,而由于多個線程共享著相同的地址空間和資源,所以會存在線程之間有可能會惡意修改或者獲取非授權(quán)數(shù)據(jù)等復(fù)雜的安全問題通孽。
U霰凇!行剂!基于以上知識點厚宰,說明下什么是瀏覽器內(nèi)核。
瀏覽器內(nèi)核
簡單來說瀏覽器內(nèi)核是通過取得頁面內(nèi)容澈蝙、整理信息(應(yīng)用CSS)撵幽、計算和組合最終輸出可視化的圖像結(jié)果,通常也被稱為渲染引擎漏麦。從上面我們可以知道况褪,Chrome瀏覽器為每個tab頁面單獨啟用進(jìn)程测垛,因此每個tab網(wǎng)頁都有由其獨立的渲染引擎實例。
瀏覽器內(nèi)核是多線程
瀏覽器內(nèi)核是多線程号涯,在內(nèi)核控制下各線程相互配合以保持同步锯七,一個瀏覽器通常由以下常駐線程組成:
- GUI 渲染線程
- JavaScript引擎線程
- 定時觸發(fā)器線程
- 事件觸發(fā)線程
- 異步http請求線程
GUI渲染線程
GUI渲染線程負(fù)責(zé)渲染瀏覽器界面HTML元素,當(dāng)界面需要重繪(Repaint)或由于某種操作引發(fā)回流(reflow)時,該線程就會執(zhí)行眉尸。在Javascript引擎運行腳本期間,GUI渲染線程都是處于掛起狀態(tài)的,也就是說被”凍結(jié)”了.
Javascript引擎線程
Javascript引擎,也可以稱為JS內(nèi)核霉祸,主要負(fù)責(zé)處理Javascript腳本程序袱蜡,例如V8引擎。Javascript引擎線程理所當(dāng)然是負(fù)責(zé)解析Javascript腳本奔穿,運行代碼巫橄。
Javascript是單線程的
Javascript是單線程的, 那么為什么Javascript要是單線程的?
這是因為Javascript這門腳本語言誕生的使命所致:JavaScript為處理頁面中用戶的交互宾舅,以及操作DOM樹彩倚、CSS樣式樹來給用戶呈現(xiàn)一份動態(tài)而豐富的交互體驗和服務(wù)器邏輯的交互處理。如果JavaScript是多線程的方式來操作這些UI DOM蔬蕊,則可能出現(xiàn)UI操作的沖突岸夯; 如果Javascript是多線程的話们妥,在多線程的交互下,處于UI中的DOM節(jié)點就可能成為一個臨界資源旅赢,假設(shè)存在兩個線程同時操作一個DOM惑惶,一個負(fù)責(zé)修改一個負(fù)責(zé)刪除带污,那么這個時候就需要瀏覽器來裁決如何生效哪個線程的執(zhí)行結(jié)果。當(dāng)然我們可以通過鎖來解決上面的問題报破。但為了避免因為引入了鎖而帶來更大的復(fù)雜性雷绢,Javascript在最初就選擇了單線程執(zhí)行翘紊。
進(jìn)一步說明:javascript的單線程
javascript引擎負(fù)責(zé)解釋和執(zhí)行javascript代碼的線程只有一個藐唠,稱為主線程。js還有其他的線程稱為工作線程踪宠。
主線程上只執(zhí)行同步任務(wù)柳琢。
- 工作進(jìn)程
瀏覽器還有還有其他的線程,例如:
處理 ajax 的線程柬脸,dom事件線程倒堕、定時器線程、讀寫文件的線程等媳搪。這些被稱為工作進(jìn)程
這些線程可能存在于js引擎之中或者之外骤宣, 稱為工作線程
工作線程的任務(wù)完成之后涯雅, 會推入到一個任務(wù)隊列(task queue)
擴(kuò)展:JavaScrpt 的異步編程
js引擎只執(zhí)行同步任務(wù), 異步任務(wù)會有工作線程來執(zhí)行。
- 異步過程
當(dāng)需要進(jìn)行異步操作(定時器精刷、ajax請求蔗候、dom事件注冊等), 主線程會發(fā)一個異步任務(wù)的請求锈遥, 相應(yīng)的工作線程接受請求; 當(dāng)工作線程完成工作之后所灸, 通知主線程丽惶;主線程接收到通知之后, 會執(zhí)行一定的操作(回調(diào)函數(shù))爬立。
GUI 渲染線程 與 JavaScript引擎線程互斥钾唬!
由于JavaScript是可操縱DOM的,如果在修改這些元素屬性同時渲染界面(即JavaScript線程和UI線程同時運行),那么渲染線程前后獲得的元素數(shù)據(jù)就可能不一致了抡秆。因此為了防止渲染出現(xiàn)不可預(yù)期的結(jié)果奕巍,瀏覽器設(shè)置GUI渲染線程與JavaScript引擎為互斥的關(guān)系,當(dāng)JavaScript引擎執(zhí)行時GUI線程會被掛起儒士,GUI更新時的止,則會被保存在一個隊列中等到引擎線程空閑時立即被執(zhí)行着撩。
JS阻塞頁面加載
從上面我們可以推理出诅福,由于GUI渲染線程與JavaScript執(zhí)行線程是互斥的關(guān)系,當(dāng)瀏覽器在執(zhí)行JavaScript程序的時候拖叙,GUI渲染線程會被保存在一個隊列中权谁,直到JS程序執(zhí)行完成,才會接著執(zhí)行憋沿。因此如果JS執(zhí)行的時間過長旺芽,這樣就會造成頁面的渲染不連貫,導(dǎo)致頁面渲染加載阻塞的感覺辐啄。簡單理解采章,為什么要有js阻塞,因為Javascript代碼可能會修改DOM樹的結(jié)構(gòu)壶辜。
定時觸發(fā)器線程
瀏覽器定時計數(shù)器并不是由JavaScript引擎計數(shù)的, 因為JavaScript引擎是單線程的, 如果處于阻塞線程狀態(tài)就會影響計時的準(zhǔn)確, 因此通過單獨線程來計時并觸發(fā)定時是更為合理的方案悯舟。
事件觸發(fā)線程
當(dāng)一個事件被觸發(fā)時該線程會把事件添加到待處理隊列的隊尾,等待JS引擎的處理砸民。這些事件可以是當(dāng)前執(zhí)行的代碼塊如定時任務(wù)抵怎、也可來自瀏覽器內(nèi)核的其他線程如鼠標(biāo)點擊、AJAX異步請求等岭参,但由于JS的單線程關(guān)系所有這些事件都得排隊等待JS引擎處理反惕。
異步http請求線程
XMLHttpRequest在連接后是通過瀏覽器新開一個線程請求, 在檢測到狀態(tài)變更時演侯,如果設(shè)置有回調(diào)函數(shù)姿染,異步線程就產(chǎn)生狀態(tài)變更事件放到 JavaScript引擎的處理隊列中等待處理。
參考
http://imweb.io/topic/58e3bfa845e5c13468f567d5
http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html
https://segmentfault.com/a/1190000009975744