程式與執行緒、同步與非同步、阻塞與非阻塞、併發與並行

YXi發表於2019-05-22

程式(Process) 與 執行緒(Thread)

  • 程式(Process):

程式是Windows系統中的一個基本概念,它包含著一個執行程式所需要的資源。一個正在執行的應用程式在作業系統中被視為一個程式, 程式可以包括一個或多個執行緒。 執行緒是作業系統分配處理器時間的基本單元,在程式中可以有多個執行緒同時執行程式碼。程式之間是相對獨立的,一個程式無法訪問另一個程式的資料(除非利用分散式計算方式),一個程式執行的失敗也不會影響其他程式的執行,Windows系統就是利用程式把工作劃分為多個獨立的區域的。程式可以理解為一個程式的基本邊界。是應用程式的一個執行例程,是應用程式的一次動態執行過程


  • 執行緒(Thread):

執行緒是程式中的基本執行單元,是作業系統分配CPU時間的基本單位, 一個程式可以包含若干個執行緒, 在程式入口執行的第一個執行緒被視為這個程式的主執行緒。在.NET應用程式中,都是以Main()方法作為入口的,當呼叫此方法時系統就會自動建立一個主執行緒。執行緒主要是由CPU暫存器、呼叫棧和執行緒本地儲存器組成的。CPU暫存器主要記錄當前所執行執行緒的狀態,呼叫棧主要用於維護執行緒所呼叫到的記憶體與資料,TLS主要用於存放執行緒的狀態資訊。


  • 程式(Process)與執行緒(Thread)的區別:

    • 程式和執行緒的主要差別在於它們是不同的作業系統資源管理方式。
    • 程式有獨立的地址空間,一個程式崩潰後,在保護模式下不會對其它程式產生影響,而執行緒只是一個程式中的不同執行路徑。
    • 執行緒有自己的堆疊和區域性變數,但執行緒之間沒有單獨的地址空間,一個執行緒死掉就等於整個程式死掉,所以多程式的程式要比多執行緒的程式健壯,但在程式切換時,耗費資源較大,效率要差一些。
    • 對於一些要求同時進行並且又要共享某些變數的併發操作,只能用執行緒,不能用程式。
    • 一個程式至少有一個程式,一個程式至少有一個執行緒.
    • 執行緒的劃分尺度小於程式,使得多執行緒程式的併發性高。
    • 程式在執行過程中擁有獨立的記憶體單元,而多個執行緒共享記憶體,從而極大地提高了程式的執行效率。
    • 執行緒在執行過程中與程式還是有區別的。每個獨立的執行緒有一個程式執行的入口、順序執行序列和程式的出口。但是執行緒不能夠獨立執行,必須依存在應用程式中,由應用程式提供多個執行緒執行控制。
    • 從邏輯角度來看,多執行緒的意義在於一個應用程式中,有多個執行部分可以同時執行。但作業系統並沒有將多個執行緒看做多個獨立的應用,來實現程式的排程和管理以及資源分配。這就是程式和執行緒的重要區別。


同步(Sync) 和 非同步(Async)

  • 同步(Sync):

同步,就是發出一個功能呼叫時,在沒有得到結果之前,該呼叫就不返回或繼續執行後續操作。簡單來說,同步就是必須一件一件事做,等前一件做完了才能做下一件事。


  • 非同步(Async):

非同步與同步相對,當一個非同步過程呼叫發出後,呼叫者在沒有得到結果之前,就可以繼續執行後續操作。當這個呼叫完成後,一般通過狀態、通知和回撥來通知呼叫者。對於非同步呼叫,呼叫的返回並不受呼叫者控制。
通知呼叫者的三種方式:

  1. 狀態:
      即監聽被呼叫者的狀態(輪詢),呼叫者需要每隔一定時間檢查一次,效率會很低。
  2. 通知:
      當被呼叫者執行完成後,發出通知告知呼叫者,無需消耗太多效能。
  3. 回撥:
      與通知類似,當被呼叫者執行完成後,會呼叫呼叫者提供的回撥函式。

  • 同步(Sync)與非同步(Async)的區別:  

簡單的說,就是請求發出後,是否需要等待結果,才能繼續執行其他操作。



阻塞與非阻塞

  • 阻塞和非阻塞這兩個概念與程式(執行緒)等待訊息通知(無所謂同步或者非同步)時的狀態有關。也就是說阻塞與非阻塞主要是程式(執行緒)等待訊息通知時的狀態角度來說的。
  • 阻塞和非阻塞關注的是程式在等待呼叫結果(訊息,返回值)時的狀態。
  • 阻塞呼叫是指呼叫結果返回之前,當前執行緒會被掛起。呼叫執行緒只有在得到結果之後才會返回。
  • 非阻塞呼叫指在不能立刻得到結果之前,該呼叫不會阻塞當前執行緒。


併發 與 並行

  • 併發: 在作業系統中,是指一個時間段中有幾個程式都處於已啟動執行到執行完畢之間,且這幾個程式都是在同一個處理機上執行,但任一個時刻點上只有一個程式在處理機上執行。當有多個執行緒在操作時,如果系統只有一個CPU,則它根本不可能真正同時進行一個以上的執行緒,它只能把CPU執行時間劃分成若干個時間段,再將時間 段分配給各個執行緒執行,在一個時間段的執行緒程式碼執行時,其它執行緒處於掛起狀。.這種方式我們稱之為併發(Concurrent)。

  • 並行: 當系統有一個以上CPU時,則執行緒的操作有可能非併發。當一個CPU執行一個執行緒時,另一個CPU可以執行另一個執行緒,兩個執行緒互不搶佔CPU資源,可以同時進行,這種方式我們稱之為並行(Parallel)。

  • 併發 與 並行的區別:

    • 併發的關鍵是你有處理多個任務的能力, 不一定要同時進行。
    • 並行的關鍵是你有 同時 處理多個任務的能力。


理解 同步阻塞、同步非阻塞、非同步阻塞、非同步非阻塞

  • 同步/非同步關注的是訊息通知的機制,而阻塞/非阻塞關注的是程式(執行緒)等待訊息通知時的狀態。

以小倩下載檔案打個比方,從這兩個關注點來說明這兩組概念,希望能夠更好的促進大家的理解。

同步阻塞: 小倩一直盯著下載進度條,到 100% 的時候就完成。
同步體現在: 等待下載完成通知;
阻塞體現在: 等待下載完成通知過程中,不能做其他任務處理;

同步非阻塞: 小倩提交下載任務後就去幹別的,每過一段時間就去瞄一眼進度條,看到 100% 就完成。
同步體現在: 等待下載完成通知,但是要必須在;
非阻塞體現在: 等待下載完成通知過程中,去幹別的任務了,只是時不時會瞄一眼進度條;【小倩必須要在兩個任務間切換,關注下載進度】

非同步阻塞: 小倩換了個有下載完成通知功能的軟體,下載完成就“叮”一聲。不過小倩仍然一直等待“叮”的聲音(看起來很傻,不是嗎?)。
非同步體現在: 下載完成“叮”一聲通知;
阻塞體現在: 等待下載完成“叮”一聲通知過程中,不能做其他任務處理;

非同步非阻塞: 仍然是那個會“叮”一聲的下載軟體,小倩提交下載任務後就去幹別的,聽到“叮”的一聲就知道完成了。
非同步體現在: 下載完成“叮”一聲通知;
非阻塞體現在: 等待下載完成“叮”一聲通知過程中,去幹別的任務了,只需要接收“叮”聲通知即可;【軟體處理下載任務,小倩處理其他任務,不需關注進度,只需接收軟體“叮”聲通知,即可】

也就是說,同步/非同步是“下載完成訊息”通知的方式(機制),而阻塞/非阻塞則是在等待“下載完成訊息”通知過程中的狀態(能不能幹其他任務),在不同的場景下,同步/非同步、阻塞/非阻塞的四種組合都有應用。


所以,綜上所述,同步和非同步僅僅是關注的訊息如何通知的機制,而阻塞與非阻塞關注的是等待訊息通知時的狀態。也就是說,同步的情況下,是由處理訊息者自己去等待訊息是否被觸發,而非同步的情況下是由觸發機制來通知處理訊息者,所以在非同步機制中,處理訊息者和觸發機制之間就需要一個連線的橋樑:在小倩的例子中,這個橋樑就是軟體“叮”的聲音。

同步/非同步 與 阻塞/非阻塞

  1. 同步阻塞形式
      效率是最低的

  2. 非同步阻塞形式
      非同步操作是可以被阻塞住的,只不過它不是在處理訊息時阻塞,而是在等待訊息通知時被阻塞。

  3. 同步阻塞形式
     實際上是效率低下的,(想象一下你一邊幹別的事情一邊還需要抬頭看下載完成沒有)

  4. 非同步非阻塞形式
      效率更高


^_<

相關文章