這幾天在思考如何改進原型在多個客戶端的情況下的效能,特地溫習了一下多程序和多執行緒的一些知識。
在linux下程序的程序和執行緒在核心看來區別很小,都是乙個可排程單元,都擁有記憶體管理結構等等。但是關鍵的差別是程序的資源都是私有的,而執行緒則是和別人共享的,所以執行緒的上下文切換可能比程序的開銷要小很多,而程序則更加的安全,因為執行緒有可能會破壞或者說「竊取」別人的資料。因此,程序間通訊ipc的幾個手段,比如說訊號量,訊息佇列等都需要最終依靠核心通過檔案系統或者是網路棧來完成(pipe不知道如何實現的,沒有看過);而執行緒間通訊則要高效得多,很多資料都是共享的。
多核和多cpu系統。多核指的是單個晶元上整合了多個cpu,這些cpu間的通訊花銷也比較小;多cpu系統的話,cpu位於單獨的晶元中,通訊花銷相對而言較大。多cpu系統如果只用單一匯流排訪問ram的時候,也要考慮共享和同步的問題,也是乙個很大的花銷(不過不是很清楚這個架構,記得應該是有好幾種組成方式的,這只是其中一種)。
在多核、多cpu系統中,泛泛而言是多執行緒還是多程序要好似乎沒有多大的意義,需要根據你的應用情況而定。如果程序間通訊是一筆很大的開銷,那麼更換ipc方式(共享記憶體的通訊效率很高,記憶體直接對映在程序的私有位址空間。但是需要處理好共享的問題)或者換成多執行緒的方式。另外,在以前的筆記中有看到乙個例子,乙個在單核機器上跑得很好的應用在多核上面共享衝突就很嚴重,因為多核上面是真正的併發執行,以前序列執行方式下沒有的問題這裡都可能碰到。所以碰到類似效能問題需要多試驗和分析,這需要有非常廣泛的知識背景,否則可能都不會懷疑到上面去。
具體到原型,原型實際上完成的工作很簡單。主程序在服務埠上偵聽,有服務請求則fork乙個子程序來響應,子程序接受客戶端傳送過來的資料,稍作處理後傳送到資料對應的fifo中,每個fifo的另外一段都有乙個響應的程序在負責將資料存入到乙個臨時的快取檔案中;當達到一定條件後,fifo的接受程序執行mysql的load語句,load完成後繼續響應fifo的輸入。
各子程序之間的資料共享唯一的就是fifo,有兩種選擇,一是所有子程序寫入的資料小於一次原子寫的大小;或者利用訊號量同步。我採取的是第二種方法,因為當初想更好的利用網路。這樣看來多程序、多執行緒都差別不大。瓶頸在於檔案寫和load上面,因為fifo採用的事block寫的方式,所以在load的時候,子程序必須等待;在寫臨時緩衝檔案的時候也必須等待,如果這幾步能大大減少時間消耗,那麼效能必然提高。non-block寫fifo的方式不適合,這裡資料量很大,如果讀端沒有及時處理資料,管道可能很快就滿了,並且我也沒有查到fifo確切的緩衝大小,有篇文章似乎提到近似於檔案系統的大小,但是不是很確定。
所以下週的工作將是調優。途徑的話,能否將各個步驟用單獨的程序徹底的解耦呢?或者更徹底一點,程序單獨快取,另外乙個程序負責掃瞄各個緩衝檔案?這樣的話,各個程序間同步的工作量可能變大,並且會觸發密集的load動作,cpu的利用率可能會瞬間非常的高,可不可以接受呢?
其實現在原型的效能已經超過需求的值了,這裡純粹是力求讓他變得更棒。
多程序,多執行緒
多工程式設計 通過應用程式利用多個計算機核心達到多工同時執行的 目的,從此來提公升程式執行效率 多程序,多執行緒 程序 程式在計算機中一次執行的過程 程式 靜態的描述,不占有計算機資源 程序 是乙個動態的過程,占有cpu,記憶體等計算機資源 有一定的生命週期 同乙個程式,每次執行都是不同的程序,因為...
多執行緒 多程序
是什麼?能幹什麼?單執行緒情況下,執行效率低。系統的資源沒有得到充分利用。計算密集型 運算量比較大 io密集型 cpu空閒,輸入輸出較多 怎麼幹?爬蟲 io密集型 多執行緒 橫向 所有的程式的執行都在乙個執行緒中,程式啟動時,啟動多執行緒,每個執行緒跑同樣的 縱向 將程式進行拆分,每個執行緒跑特定的...
多執行緒 多程序
執行緒同步 lock rlock semaphores condition concurrent執行緒池編碼 多程序程式設計 multiprocessing 程序間通訊 gil global interpreter lock 全域性直譯器鎖 python中的乙個執行緒對應於c語言中的乙個執行緒 gi...