關於多執行緒的一點總結

2021-04-14 08:19:59 字數 2048 閱讀 3052

昨天又在toplanguage上看到一些關於輕量級執行緒的討論,於是對其中很有用的一段話轉過來、記錄下來以供自己日後慢慢研究。

下面是由[email protected]發表在toplanguage上的

1. process per connection / thread per connection

這在連線數不多的時候編碼方便. 並且, 在連線數不多而要求網路吞吐量高的場合, 這種方式是最容易實現, 效果也好.

2. 單一 selector/preactor

需要編寫大量的狀態機**, 比較麻煩. 配合 epoll/kqueue/ devpoll 等機制, 沒有 io block 問題的時候, 這種模式可 以輕易處理大量連線, cpu 消耗少.

需要注意的是, 檔案訪問不一定會造成大的 io block, 看業務目標和設計. 例如, 傳送檔案內容的時候, 可以使用 sendfile 呼叫, 或者 (有人提出過, 我還沒有研 究過) 將檔案 mmap 到記憶體中, 然後用 zero copy api 去傳送這段記憶體.

外界的資料庫訪問之類的, 則一定會造成 block.

3. 執行緒池

half-sync / half-async 方式 乙個 selector 負責接收請求, 一堆執行緒處理請求 缺點是 切換的 thread context 太多, 對 cpu cache 也不利.

leader / follower 方式 優點是減少了 thread context 切換, 對 cpu cache 也更有利. ace 的書上寫這個模式的缺點是, 編寫程式更複雜.

但是根據我自己的實踐, 這裡面還有乙個對效能很不利的點:

hs ha 方式, selector 可以有很多資料作為自己執行緒的私有資料, 訪問的時候不 必加鎖.

領導者跟隨者模式中, 由於所有執行緒都可以訪問所有的資料結構, 造成所有的資料 訪問之前都需要加鎖(可能有的資料結構: 傳送佇列, 全域性連線表 或者 os 具體 poll 設施的資料結構), 這在多core 的情況下, 會引起很大的效能損失. 如果使用小的加鎖粒度, 那麼要申請的鎖數目眾多, 做一件事情可能要加解多次鎖; 如果 使用大粒度鎖, 那麼鎖競爭衝突可能會嚴重.

我沒有做實際的測試, 但是擔心領導者追隨者這種方式, 在大連線數, 多 cpu core 的情況下表現會差, 所以放棄了這種方式.

我現在寫的庫, 實際上是使用 ha hs 方式, 但是, 多數簡單的任務, 直接就在 selector 執行緒中處理了, 計算量大的任務, 或者是有 io block 的任務, 才交給 執行緒池進行處理, 對於這種複雜的任務來說, thread context 的切換開銷, cpu cache 的損失, 也就不算什麼了.

4. erlang 的方式

我想過寫狀態機不方便, 如果能夠象寫順序執行的**一樣寫**就好了, 但是再 想到要處理的種種問題, 以及狀態機其實寫熟了也就那樣了, 就算了 :)

btw: ace 的selector **, 在事件發生的時候, 先將這個事件源上的事件關閉, 處理完了再開啟, 這在大連線數的情況下會造成很大的開銷, os call 的開銷不小.

對應的我也列出我對上面處理方法的理解:

1.thread per connection

由於我們現在做的乙個com介面中實現對請求的處理就是thread per connection,確實這種方法實現起來最簡單,但是由於發現我們的請求大多數都是短請求,資料量也少,所以很不適合這種模型,頻繁的建立、銷毀執行緒,是一種很浪費的操作,所以在考慮之後重新設計。(不過由於時間和技術的一些限制,暫時只能先用上了)

2.selector/preactor

不是很明白上面對應的地方,我是理解為select模型的。select模式,之前我也寫過乙個小的測試程式,還不是很理解,應該是由系統來維護讀集和寫集,然後當判斷可讀或者可寫時進行適當的操作。如果理解的正確,那麼對於多執行緒,我還是覺得這個是我現在知識範圍內最好的解決方案。

3.執行緒池

哈哈,這個比起select還是好懂一些,但是內在的呼叫機制還沒有研究,所以也就是只能從效能上說確實比第一種好,而且實現起來應該也不是很難。

4.erlang

之前就沒聽說過。唉……看來「革命尚未成功,同志仍需努力」!

關於多執行緒的一點感想

寫了這麼多年多執行緒程式,多執行緒到底是用來幹嘛的,可能這是個很白痴的問題,就我的親身經歷看開主要是因為一下兩點 1.提公升程式效率 2.使得程式可以非同步執行,乙個執行緒幹這個活,另乙個執行緒幹另乙個活 嚴格來說,感覺這還是為了提公升程式效率,因為cpu本身就是在不同執行緒之間切換的,兩個執行緒能...

關於多執行緒的一點補充

多執行緒與工作流一文中將多執行緒設計思路與工作流設計思路進行了一下對比,突然想到了這個問題,就順手發上來了 在開發wf的宿主程式中,我們或多或少的會用到多執行緒,如果宿主是winform程式,也有可能會用到跨執行緒訪問ui控制項的需要 看一下在net1.1中的執行緒訪問ui控制項 private v...

關於執行緒安全的一點總結

先寫一點,以後再慢慢改 1.synchronized 同步鎖 以時間換取安全,效率低下 2.threadlocal 以空間換取時間,比較消耗資源,安全 3.單例模式用雙重鎖比價好,執行緒安全且效率還行 4.執行緒的掛起有wait 被動,需要外界喚起 sleep 主動,不釋放資源 當然,叫掛起好像有點...