多線程程序開發簡介
一、線程 / Threading
線程這個概念大概在1993年后才慢慢流行起來。線程是操作系統進行調度的最小單位,擁有少量的資源,如寄存器和棧。線程的特點是共享地址空間,從而高效地共享數據。多線程的價值是更好地發揮多核處理器的功能。
二、使用線程的幾種方式
1. 流水線
每個線程反復地在數據系列集上執行同一種操作,并把操作結果傳遞給下一步驟的其他線程,這就是流水線方式。
在流水線方式中,數據元素流串行地被一組線程順序處理。每個線程依次在每個元素上執行一個特定的操作,并將結果傳遞給流水線中的下一個線程。
2. 工作組
每個線程在自己的數據上執行操作。工作組中的線程可能執行同樣的操作,也可能執行不同的操作,但是它們一定獨立地執行。
在工作組模式中,數據由一組線程分別獨立處理。通常有兩種模式:SIMD(single instruction, multiple data, 單指令多數據流)和MIMD(multiple instruction, multiple data, 多指令多數據)。SIMD是指所有的工作線程在不同的數據部分上執行相同的操作,MIMD是指工作組中的線程在不同的數據上執行不同的操作。
3. 客戶端 / 服務器
一個客戶端為每一件工作與一個獨立的服務器“訂契約”。通?!坝喥跫s”是匿名的,一個請求通過某種接口提交。
在客戶服務器系統中,客戶端請求服務器對一組數據執行某個操作。服務器獨立地執行操作——客戶端或者等待服務器執行,或者并行地執行,在后面需要時再查找結果。
三、線程的好處
多線程編程具有如下優點:
在多處理器系統中開發程序的并行性。并行性這一優點需要特殊硬件支持,其他優點對硬件無要求。
在等待慢速外設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和定時器;線程池用作計算,可以是任務隊列或生產者消費者隊列。
小結
線程無法給所有編程問題提供最好的解決方案。線程并不總是容易使用,也不能保證總是提供更好的性能。某些問題本身是非并發的,使用線程只能降低程序的性能并使程序復雜。大部分程序有一些本質上的并發,這種情況下,多線程程序通常比串行程序更快、響應性能更好,而且比實現同樣功能的非線程異步程序更易于開發和維護。(張玉遵 | 天存信息)
多線程 網站 網絡 運維 通用安全
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。