Try   HackMD

2016q3 Homework2 (phonebook-concurrent)

contributed by <linachiu>

Concurrency (並行) vs. Parallelism (平行)

Task: 一件任務

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • Concurrency: 兩個任務分配到一個CPU核心,在取得的時間片段中交互執行

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • Parallelism: 有兩個CPU,同個問題分配到兩個CPU上同時執行

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

一些造成等待時間變長的 blocking IO

  • fgets > 可用 mmap()改善
  • malloc() > 可開一個 memory pool 將 linked list會用到的空間先開好

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Thread Pool

在介紹Thread之前,我們必須先把Program和Process這兩個觀念作一個釐清。

  • Program: 一群程式碼的集合,用以解決特定的問題。以物件導向的觀念來類比,相當於Class。

  • Process: 由Program所產生的執行個體,一個Program可以同時執行多次,產生多個Process。以物件導向的觀念來類比,相當於Object。每一個Process又由以下兩個東西組成

    • 一個Memory Space :相當於Object的variable,不同Process的Memory Space也不同,彼此看不到對方的Memory Space。
    • 一個以上的Thread :Thread代表從某個起始點開始(例如main),到目前為止所有函數的呼叫路徑,以及這些呼叫路徑上所用到的區域變數。當然程式的執行狀態,除了紀錄在主記憶體外,CPU內部的暫存器(如Program Counter, Stack Pointer, Program Status Word等)也需要一起紀錄。所以Thread又由下面兩項組成
      • Stack: 紀錄函數呼叫路徑,以及這些函數所用到的區域變數
      • 目前CPU的狀態

Thread的重點如下

  • 一個Process可以有多個Thread。

  • 同一個Process內的Thread使用相同的Memory Space,但這些Thread各自擁有其Stack。換句話說,Thread能透過reference存取到相同的Object,但是local variable卻是各自獨立的。

  • 作業系統會根據Thread的優先權以及已經用掉的CPU時間,在不同的Thread作切換,以讓各個Thread都有機會執行。

Thread Pool

  • Thread 執行緒常被定義為一個輕量的(Lightweight) Process,可用來處理 request,
    然而雖然是輕量,但在產生 Thread 時仍會有 overhead,此時若 request 量太大,
    又沒有善加管理這些 Thread 的話,就會拖累整體系統的效能。
    為了解決這種類型的效能問題,所以就有了 Thread Pool 的概念產生。

  • Thread Pool 的概念如同其名,就是一個 Thread 的 Pool,其中有固定或變動量的 Thread,當 request 進來時,若有閒置的 Thread 就執行,若沒有的話,可能產生新的 Thread 或把 request 放入 queue 中等待被執行,當一條 Thread 執行完工作而 queue 中仍有 request 在等待時,此 Thread 應該要被分發新的 request 並處理。

  • 由以上幾行,我們可以看出 Thread Pool 的工作有:

    • 管控 Thread 的產生與回收
    • 分發 Thread 處理 request
    • 處理 request 的 queue

Lock-free Thread Pool

大多數 thread pool 實做都離不開 lock 的使用,如 pthread_mutex 結合 (condition variable) pthread_cond。一般來說,lock 的使用對於程式效能影響較大,雖然現有的 pthread_mutex 在 lock 的取得 (acquire) 與釋放,已在 Linux 核心和對應函式庫進行效能提昇,但我們仍會希望有不仰賴 lock 的 thread pool 的實做。

常見 thread pool 實做原理

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

如上圖所示,workqueue (工作佇列) 由 main thread (主執行緒) 和 worker thread 共享,main thread 將任務放進 workqueue,worker thread 從 workqueue 中取出任務執行。要注意到,共享 workqueue 的操作必須在 mutex 的保護下安全進行,main thread 將任務放進 workqueue 時,若偵測到目前待執行的工作數目小於 worker thread 總數,則要透過 condition variable 喚醒可能處於等待狀態的 worker thread。