進程與線程

今天學習的內容是進程和線程,光看文字你們可能以爲會很陌生,不理解這兩個詞語是什麼意思,尤爲是線程,看起來會更爲抽象,而進程可能你們會在不少地方多看獲得他們存在的身影。前端

好比說,在任務管理器中瀏覽器

 

 

從上面兩個圖中,咱們能夠清楚的認識到,什麼是進程,從第一張圖能夠看到,映像名稱下每一條都是一個進程,後面是每一條進程的cpu佔有率以及內存佔用。服務器

進程定義:進程就是在系統內存中加載運行的程序;多線程

通俗來說:異步

  計算機的核心是CPU,它承擔了全部的計算任務。它就像一座工廠,時刻在運行。 
  假定工廠的電力有限,一次只能供給一個車間使用。也就是說,一個車間開工的時候,其餘車間都必須停工。背後的含義就是,單個CPU一次只能運行一個任務。進程就比如工廠的車間,它表明CPU所能處理的單個任務。任一時刻,CPU老是運行一個進程,其餘進程處於非運行狀態。函數

2.線程oop

  圖接上文,一個車間(進程)裏,能夠有不少工人(線程)。他們協同完成一個任務。車間的空間是工人們共享的,好比許多房間是每一個工人均可以進出的。這象徵一個進程的內存空間是共享的,每一個線程均可以使用這些共享內存。 
     但是,每間房間的大小不一樣,有些房間最多隻能容納一我的,好比廁所。裏面有人的時候,其餘人就不能進去了。這表明一個線程使用某些共享內存時,其餘線程必須等它結束,才能使用這一塊內存。一個防止他人進入的簡單方法,就是門口加一把鎖。先到的人鎖上門,後到的人看到上鎖,就在門口排隊,等鎖打開再進去。這就叫」互斥鎖」(Mutual exclusion,縮寫 Mutex),防止多個線程同時讀寫某一塊內存區域。 
  還有些房間,能夠同時容納n我的,好比廚房。也就是說,若是人數大於n,多出來的人只能在外面等着。這比如某些內存區域,只能供給固定數目的線程使用。這時的解決方法,就是在門口掛n把鑰匙。進去的人就取一把鑰匙,出來時再把鑰匙掛回原處。後到的人發現鑰匙架空了,就知道必須在門口排隊等着了。這種作法叫作」信號量」(Semaphore),用來保證多個線程不會互相沖突。不難看出,mutex是semaphore的一種特殊狀況(n=1時)。也就是說,徹底能夠用後者替代前者。可是,由於mutex較爲簡單,且效率高,因此在必須保證資源獨佔的狀況下,仍是採用這種設計。佈局

  這樣看來,線程是否是就不難以理解了,線程能夠說是進程的實體化,線程之間相互配合,完成進程分配下來的任務。性能

  線程是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位。線程本身基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器、一組寄存器和棧),可是它可與同屬一個進程的其餘的線程共享進程所擁有的所有資源。學習

3.進程與線程之間的區別

除此以外,進程與線程之間的區別還有:

  • 進程是由系統建立的,而且會爲它分配獨立地址空間,加載(複製)所須要的存在硬盤中的數

    據到內存,進程建立時候會建立一個主線程;

  • 線程是進程建立的,直接可以使用進程的資源,而且同個進程中的線程共享進程的地址空間

    資源,所以建立進程會比建立線程要耗費資源;

  • 進程和線程都可以獨立完成任務,進程完成的任務要比線程完成的任務複雜;

  • 進程控制不了兄弟進程,只能控制子進程,同個進程中的線程能夠控制兄弟線程

 4.瀏覽器進程

  • Browser進程:瀏覽器的主進程(負責協調、主控),只有一個
  • 第三方插件進程:每種類型的插件對應一個進程,僅當使用該插件時才建立
  • GPU進程:最多一個,用於3D繪製
  • 瀏覽器渲染進程(內核):默認每一個Tab頁面一個進程,互不影響,控制頁面渲染,腳本執行,事件處理等(有時候會優化,如多個空白tab會合併成一個進程)

  在這幾個進程中,咱們主要了解瀏覽器渲染進程。它是對咱們前端操做來講最重要的一個進程,由於裏面包含了js引擎進程。這一章,咱們大概瞭解一下渲染進程中中的這幾個線程,對咱們下一章瞭解

js Event-Loop事件機制作個鋪墊。

  瀏覽器渲染進程包含的幾個線程:

  1. GUI渲染線程

    • 負責渲染瀏覽器界面,解析HTML,CSS,構建DOM樹和RenderObject樹,佈局和繪製等。
    • 當界面須要重繪(Repaint)或因爲某種操做引起迴流(reflow)時,該線程就會執行
    • 注意,GUI渲染線程與JS引擎線程是互斥的,當JS引擎執行時GUI線程會被掛起(至關於被凍結了),GUI更新會被保存在一個隊列中等到JS引擎空閒時當即被執行。
  2. JS引擎線程

    • 也稱爲JS內核,負責處理Javascript腳本程序。(例如V8引擎)
    • JS引擎線程負責解析Javascript腳本,運行代碼。
    • JS引擎一直等待着任務隊列中任務的到來,而後加以處理,一個Tab頁(renderer進程)中不管何時都只有一個JS線程在運行JS程序
    • 一樣注意,GUI渲染線程與JS引擎線程是互斥的,因此若是JS執行的時間過長,這樣就會形成頁面的渲染不連貫,致使頁面渲染加載阻塞。
  3. 事件觸發線程

    • 歸屬於瀏覽器而不是JS引擎,用來控制事件循環(能夠理解,JS引擎本身都忙不過來,須要瀏覽器另開線程協助)
    • 當JS引擎執行代碼塊如setTimeOut時(也可來自瀏覽器內核的其餘線程,如鼠標點擊、AJAX異步請求等),會將對應任務添加到事件線程中
    • 當對應的事件符合觸發條件被觸發時,該線程會把事件添加到待處理隊列的隊尾,等待JS引擎的處理
    • 注意,因爲JS的單線程關係,因此這些待處理隊列中的事件都得排隊等待JS引擎處理(當JS引擎空閒時纔會去執行)

  4. 定時觸發器線程

    • 傳說中的setIntervalsetTimeout所在線程
    • 瀏覽器定時計數器並非由JavaScript引擎計數的,(由於JavaScript引擎是單線程的, 若是處於阻塞線程狀態就會影響記計時的準確)
    • 所以經過單獨線程來計時並觸發定時(計時完畢後,添加到事件隊列中,等待JS引擎空閒後執行)
    • 注意,W3C在HTML標準中規定,規定要求setTimeout中低於4ms的時間間隔算爲4ms。
  5. 異步http請求線程

    • 在XMLHttpRequest在鏈接後是經過瀏覽器新開一個線程請求
    • 將檢測到狀態變動時,若是設置有回調函數,異步線程就產生狀態變動事件,將這個回調再放入事件隊列中。再由JavaScript引擎執行。

   

  在這裏,咱們其實能夠找到一個問題,爲什JavaScript是單線程而不是多線程語言,單線程同一個時間只能作一件事。若是JavaScript是多線程,不是能夠提升效率嗎。

  其實,js單線程是被開發時就決定的,js一開始是做爲一門輔助語言存在的,它的主要做用就是與用戶互動,減小客戶端向服務器的請求次數,設想一下,若是有一個簡單的表單有效性驗證,用戶填完一個表單,點擊提交按鈕,客戶端向服務器發送請求,等待了 30 秒的處理後,看到的倒是一條告訴你忘記填寫密碼的提示,這樣不是大大的浪費了服務器性能,也下降了用戶體驗嗎。因此它存在的用途就決定了它只能是單線程,不然會帶來很複雜的同步問題。好比,假定JavaScript同時有兩個線程,一個線程在某個DOM節點上添加內容,另外一個線程刪除了這個節點,這時瀏覽器應該以哪一個線程爲準?

  因此,爲了不復雜性,從一誕生,JavaScript就是單線程,這已經成了這門語言的核心特徵,未來也不會改變。

  爲了利用多核CPU的計算能力,HTML5提出Web Worker標準,容許JavaScript腳本建立多個線程,可是子線程徹底受主線程控制,且不得操做DOM。因此,這個新標準並無改變JavaScript單線程的本質。

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息