一、執行緒 / Threading
執行緒這個概念大概在1993年后才慢慢流行起來,執行緒是作業系統進行調度的最小單位,擁有少量的資源,如暫存器和堆疊,執行緒的特點是共享地址空間,從而高效地共享資料,多執行緒的價值是更好地發揮多核處理器的功能,
二、使用執行緒的幾種方式
1. 流水線
每個執行緒反復地在資料系列集上執行同一種操作,并把操作結果傳遞給下一步驟的其他執行緒,這就是流水線方式,
在流水線方式中,資料元素流串行地被一組執行緒順序處理,每個執行緒依次在每個元素上執行一個特定的操作,并將結果傳遞給流水線中的下一個執行緒,

2. 作業組
每個執行緒在自己的資料上執行操作,作業組中的執行緒可能執行同樣的操作,也可能執行不同的操作,但是它們一定獨立地執行,
在作業組模式中,資料由一組執行緒分別獨立處理,通常有兩種模式:SIMD(single instruction, multiple data, 單指令多資料流)和MIMD(multiple instruction, multiple data, 多指令多資料),SIMD是指所有的作業執行緒在不同的資料部分上執行相同的操作,MIMD是指作業組中的執行緒在不同的資料上執行不同的操作,

3. 客戶端 / 服務器
一個客戶端為每一件作業與一個獨立的服務器“訂契約”,通常“訂契約”是匿名的,一個請求通過某種介面提交,
在客戶服務器系統中,客戶端請求服務器對一組資料執行某個操作,服務器獨立地執行操作——客戶端或者等待服務器執行,或者并行地執行,在后面需要時再查找結果,

三、執行緒的好處
多執行緒編程具有如下優點:
在多處理器系統中開發程式的并行性,并行性這一優點需要特殊硬體支持,其他優點對硬體無要求,
在等待慢速外設I/O操作結束的同時,程式可以執行其他計算,為程式的并發提供更有效、更自然的開發方式,
一種模塊化編程模型,能清晰地表達程式中獨立事件間的相互關系,
四、執行緒的代價
1. 計算負荷
執行緒代碼中的負荷包括由于執行緒間同步所導致的直接影響,很多演算法在某些情況下可避免同步,但在幾乎任何執行緒代碼中都需要使用某種同步機制,同步很容易損失性能,
計算密集型執行緒數量若比可用的處理器多,則可能比單執行緒實作獲得更好的代碼結構,但程式性能也會更糟,這是由于多執行緒結構在要完成的作業上增加了同步和調度開銷,而可用的資源并沒有變,
2. 編程規則
執行緒模型基本思想簡單,但撰寫能在多執行緒中良好作業的代碼需要認真思考和規劃,包括同步協議,避免死鎖、競爭和優先級倒置,如果有可用的庫,應盡量使用庫代碼而不是自己撰寫,
3. 更難以除錯
除錯不可避免的改變了事件的時序,這對于串行代碼問題不大,但對于異步代碼卻是致命的,一個執行緒因除錯陷阱而運行得慢了,要跟蹤的問題可能就不會出現,除錯無法再現的錯誤是一件讓人頭疼的事情,
五、多執行緒適用場合
從功能上講,沒有什么是多執行緒能做到而單執行緒做不到的,反之亦然,
如果用很少的CPU負載就能讓IO跑滿,或者用很少的IO流量就能讓CPU跑滿,那么多執行緒就沒有什么優勢,
多執行緒的適用場景是:提高回應速度,讓IO和“計算”相互重疊,降低延遲,雖然多執行緒不能提高絕對性能,但能提高平均回應性能,
一個程式要寫成多執行緒,大致要滿足:
· 有多個CPU可用,單核機器上多執行緒無性能優勢;
· 執行緒間有共享資料,即記憶體中的全域狀態;
· 共享的資料是可以修改的; ·
· 事件的回應有優先級差異,可用專門執行緒處理高優先級事件,防止優先級反轉;
· 延遲和吞吐量同樣重要,不是簡單的IO密集或CPU密集型程式;
· 利用異步操作,如記日志,無論發日志訊息還是寫日志檔案,都不應阻塞關鍵路徑;
· 可擴展,一個好的多執行緒程式應能享受增加CPU數目帶來的好處;
· 多執行緒能有效地劃分責任與功能,讓每個執行緒的邏輯簡單,任務單一,便于編碼,
六、多執行緒常用編程模型
多執行緒常用編程模型有如下幾種:
· 每個請求創建一個執行緒,使用阻塞式IO操作(伸縮性不佳);
· 使用執行緒池,同樣使用阻塞式IO操作;
· 使用非阻塞IO+IO多路復用;
· Leader/Follower等高級模式;
1. one loop per thread
此模型下,程式里的每個IO執行緒有一個event loop(用作IO多路復用),用于處理讀寫和定時時間,event loop代表了執行緒的主回圈,需要讓哪個執行緒干活,就把timer或IO channel注冊到哪個執行緒的loop里即可,
event loop描述如下:
while there are still events to process:
e = get the next event
if there is a callback associated with e:
call the callback
2. Leader / Follower
此模型會創建一個執行緒池,每個執行緒有三種狀態:leading, following, processing,Leader執行緒負責監聽請求,其他執行緒作為follower處于等待狀態,當leader收到請求后,首先通知一個follower執行緒將其提拔為新的leader,然后自己去處理這個請求,處理完畢后加入follower執行緒等待佇列,等待下次成為leader,
Leader/Follower模式避免了執行緒動態創建和銷毀的額外開銷,將執行緒放在池中,無需交換資料,將背景關系切換、同步、資料移動和動態記憶體管理的開銷都降到了最低,

3. 推薦模式
推薦的多執行緒編程模式:one loop per thread + 執行緒池,
event loop用作IO多路復用,配合非阻塞IO和定時器;執行緒池用作計算,可以是任務佇列或生產者消費者佇列,
小結
執行緒無法給所有編程問題提供最好的解決方案,執行緒并不總是容易使用,也不能保證總是提供更好的性能,某些問題本身是非并發的,使用執行緒只能降低程式的性能并使程式復雜,大部分程式有一些本質上的并發,這種情況下,多執行緒程式通常比串行程式更快、回應性能更好,而且比實作同樣功能的非執行緒異步程式更易于開發和維護,(張玉遵 | 天存資訊)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/285632.html
標籤:其他
上一篇:委派
