聊聊執行緒與程式 & 阻塞與非阻塞 & 同步與非同步

Linda_0504發表於2019-03-01

作為一名前端的妹子,為了使自己更上一個臺階,下定決心好好提升自己的技術。先從最基礎的概念開始吧~~

執行緒與程式

概念
  • 程式是具有一定獨立功能的程式關於某個資料集合上的一次執行活動,程式是系統進行資源分配和排程的一個獨立單位.

  • 執行緒一個程式內部可能包含了很多順序執行流,每個順序執行流就是一個執行緒。 執行緒是程式的一個實體,是CPU排程和分派的基本單位,它是比程式更小的能獨立執行的基本單位。執行緒自己基本上不擁有系統資源,只擁有一點在執行中必不可少的資源(如程式計數器,一組暫存器和棧),但是它可與同屬一個程式的其他的執行緒共享程式所擁有的全部資源[一塊記憶體空間和一組系統資源].
    ···[so 難懂~~]

舉個?

  • [程式]:我們都知道程式,一個程式是靜態的,通常是存放在外存中的。而當程式被調入記憶體中執行後,就成了程式。顧名思義,程式就是進行中的程式,它是個動態的概念。是系統進行資源分配與排程的基本單位。例如在windows中,每一個開啟執行的應用程式或後臺程式,比如執行中的QQ、谷歌瀏覽器、網易雲音樂、資源管理器等都是一個程式
  • [單執行緒] 一個程式內部可能包含了很多順序執行流,每個順序執行流就是一個執行緒執行緒又有單執行緒多執行緒之分。我們用js/c/java寫的程式大部分時候都是單執行緒的程式設計。將主檔案作為程式的入口,依次執行,直到執行完全部程式碼[ps:正常情況下是醬紫,但也有可能某一個行程式碼throw an error,這樣就會被阻塞。咦,阻塞是什麼呢,且看下面~]。
  • [多執行緒]多執行緒就是有多條順序執行流“同時”執行,且它們之間互不干擾。比如,我們的web網站後臺,如果只支援單執行緒,那麼同時只能有一個使用者訪問站點,你說這點現實嗎?答案是肯定的。因此,我們應該為每一個使用者建立一個執行緒,使每個使用者能“同時”訪問站點。[同時:專業的術語應該叫併發]。

by the way,我們也看下併發並行,嗯,雖然這並不是重點…
併發: 是指,同一時刻只能有一條指令(或一個程式、一個執行緒)執行,但由於CPU的輪換執行速度超乎想象,在巨集觀上看,就有多條指令同時執行的效果
並行:是同一時刻有多條指令在多個處理機上同時執行。

兩者之間的區別

程式和執行緒的主要差別在於它們是不同的作業系統資源管理方式。程式有獨立的地址空間,一個程式崩潰後,在保護模式下不會對其它程式產生影響,而執行緒只是一個程式中的不同執行路徑。執行緒有自己的堆疊和區域性變數,但執行緒之間沒有單獨的地址空間,一個執行緒死掉就等於整個程式死掉,所以多程式的程式要比多執行緒的程式健壯,但在程式切換時,耗費資源較大,效率要差一些。但對於一些要求同時進行並且又要共享某些變數的併發操作,只能用執行緒,不能用程式。

  1. 簡而言之,一個程式至少有一個程式,一個程式至少有一個執行緒。
  2. 執行緒的劃分尺度小於程式,使得多執行緒程式的併發性高。
  3. 另外,程式在執行過程中擁有獨立的記憶體單元,而多個執行緒共享記憶體,從而極大地提高了程式的執行效率。
  4. 執行緒在執行過程中與程式還是有區別的。每個獨立的執行緒有一個程式執行的入口、順序執行序列和程式的出口。但是執行緒不能夠獨立執行,必須依存在應用程式中,由應用程式提供多個執行緒執行控制。
  5. 從邏輯角度來看,多執行緒的意義在於一個應用程式中,有多個執行部分可以同時執行。但作業系統並沒有將多個執行緒看做多個獨立的應用,來實現程式的排程和管理以及資源分配。這就是程式和執行緒的重要區別。

阻塞與非阻塞

概念

阻塞和非阻塞這兩個概念與程式(執行緒)等待訊息通知(無所謂同步或者非同步)時的狀態有關。也就是說阻塞與非阻塞主要是程式(執行緒)等待訊息通知時的狀態角度來說的。

  • 阻塞呼叫是指呼叫結果返回之前,當前執行緒會被掛起,一直處於等待訊息通知,不能夠執行其他業務。函式只有在得到結果之後才會返回。

    note: [區別於同步] 對於同步呼叫來說,很多時候當前執行緒可能還是啟用的,只是從邏輯上當前函式沒有返回而已,此時,這個執行緒可能也會處理其他的訊息

  • 非阻塞指在不能立刻得到結果之前,該函式不會阻塞當前執行緒,而會立刻返回

雖然表面上看非阻塞的方式可以明顯的提高CPU的利用率,但是也帶了另外一種後果就是系統的執行緒切換增加。增加的CPU執行時間能不能補償系統的切換成本需要好好評估。

同步與非同步

概念
  • 同步:所謂同步就是一個任務的完成需要依賴另外一個任務時,只有等待被依賴的任務完成後,依賴的任務才能算完成,這是一種可靠的任務序列。要麼成功都成功,失敗都失敗,兩個任務的狀態可以保持一致。
  • 非同步: 非同步是不需要等待被依賴的任務完成,只是通知被依賴的任務要完成什麼工作,依賴的任務也立即執行,只要自己完成了整個任務就算完成了。至於被依賴的任務最終是否真正完成,依賴它的任務無法確定,所以它是不可靠的任務序列。
  • 訊息通知: 非同步的概念和同步相對。當一個同步呼叫發出後,呼叫者要一直等待返回訊息(結果)通知後,才能進行後續的執行;當一個非同步過程呼叫發出後,呼叫者不能立刻得到返回訊息(結果)。實際處理這個呼叫的部件在完成後,通過狀態、通知和回撥來通知呼叫者。

這裡提到執行部件和呼叫者通過三種途徑返回結果:狀態、通知和回撥。使用哪一種通知機制,依賴於執行部件的實現,除非執行部件提供多種選擇,否則不受呼叫者控制。

阻塞與非阻塞,和同步非同步無關,可以阻塞等待同步執行過程完成,也可以阻塞等待非同步執行過程完成。根據以上理解, 阻塞與非阻塞/同步與非同步是可以相互組合的。

  • 同步阻塞

    呼叫者發起IO操作請求,等待IO操作完成再返回。IO操作的過程需要等待,操作執行完成後返回結果。

  • 同步非阻塞
    呼叫者發起IO操作請求,詢問IO操作的狀態,如果未完成,則立即返回;如果完成,則返回結果。IO操作的過程需要等待執行完成才返回結果。

  • 非同步阻塞
    呼叫者發起IO操作請求,等待IO操作完成再返回。IO操作的過程不需要等待,操作完成後通過通知或回撥獲得結果。

    首先需要明確: 非同步操作是可以被阻塞住的,只不過它不是在處理訊息時阻塞,而是在等待訊息通知時被阻塞。

  • 非同步非阻塞
    呼叫者發起IO操作請求,詢問IO操作的狀態,如果未完成,則立即返回;如果完成,則返回結果。IO操作的過程不需要等待,操作完成後通過通知或回撥獲得結果。

舉個?

鄙人很愛看電影,於是乎就拿下載電影來說事兒吧O(∩_∩)O哈哈~

  1. 同步阻塞:我一直抱著ipad,盯著它的下載進度條,直到 100% 才算完成。

同步體現:等待下載完成通知;

阻塞體現在: 等待下載完成通知過程中,不能做其他任務處理。

  1. 同步非阻塞: 我點選下載任務後就去洗衣服(嗯,我還是很勤勞滴~),每過一段時間就去瞄一眼進度條,看到100%就算完成。

同步體現在:等待下載完成通知

非阻塞體現在:等待下載完成通知過程中,去幹別的任務了,只是時不時會瞄一眼進度條。

  1. 非同步阻塞
    我換了個有下載完成通知功能的軟體,下載完成就“叮”一聲。不過我仍然一直等待“叮”的聲音 [似不似很傻(⊙o⊙)…]。

非同步體現在:下載完成“叮”一聲通知;

阻塞體現在:等待下載完成“叮”一聲通知
過程中,不能做其他任務處理;

  1. 非同步非阻塞:仍然是那個會“叮”一聲的下載軟體,我提交下載任務後就去幹別的,聽到“叮”的一聲就知道完成了。

非同步體現在:下載完成“叮”一聲通知;

非阻塞體現在:等待下載完成“叮”一聲通知過程中,去幹別的任務了,只需要接收“叮”聲通知即可;[軟體處理下載任務,我處理其他任務,不需關注進度,只需接收軟體“叮”聲通知,即可]

相關文章