針對 Linux 多核環境下的長期運行網路服務(無 UI、用戶態、7x24),本文系統比較單/多進程、單/多執行緒四種模式,深入分析多執行緒的真正適用場景,並給出線程分類與設計原則。
四種並發模式比較
| 模式 | 描述 | 評價 |
| 1. 單進程單執行緒 | Event loop (poll/epoll) | 不可擴展,浪費多核 |
| 2. 單進程多執行緒 | 共享記憶體空間 | 常被鄙視,實則有特定優勢 |
| 3a. 多進程單執行緒 (多 Port) | 單純複製進程 | 主流模式,簡單可靠 |
| 3b. 多進程單執行緒 (Master/Worker) | 主進程 accept,worker 處理 | 主流模式 (nginx, httpd+fastcgi) |
| 4. 多進程多執行緒 | 混合模式 | 匯聚雙方缺點,極少使用 |
必須用單執行緒的場景
- 需呼叫
fork():Linux fork() 僅複製當前執行緒,多執行緒下易死鎖(鎖被複製但持有者線程消失)。看門狗進程、啟動器屬此類。
- 限制 CPU 佔用:單執行緒在 8 核機器上最多佔 12.5% CPU,適合輔助監控程序避免搶佔核心服務資源。
多執行緒的真實優勢:降低 Latency 而非提升 Throughput
- IO 密集型:單執行緒 event loop 即可跑滿網卡/磁碟,多執行緒無吞吐增益。
- CPU 密集型:純計算任務用模式 3a 多進程即可線性擴展,無需共享記憶體。
- 關鍵價值:非搶佔 event loop 會發生優先級反轉(低優先級長任務阻塞高優先級事件)。多執行緒可將高優先級事件派發給專用執行緒,保證響應時間。
適用多執行緒的判斷清單
- ✅ 多 CPU 核心可用
- ✅ 執行緒間有可變共享資料(否則用進程+共享記憶體)
- ✅ 提供非均質服務(優先級差異大,需防優先級反轉)
- ✅ Latency 與 Throughput 同等重要
- ✅ 大量異步操作(Logging、DB、外部 API)需不阻塞關鍵路徑
- ✅ 能 Scale-up(受益於核心數增加,現代 8-16 核常態)
- ✅ 性能可預測(負載增長平滑衰減,執行緒數固定不隨負載爆增)
- ✅ 能清晰劃分職責(IO 執行緒、計算執行緒、第三方庫執行緒)
實例:叢集管理 Master 進程設計
- 獨佔 8 核機器,單執行緒浪費 87.5% 算力。
- 叢集狀態全內存共享可變,多進程同步成本極高。
- 核心指標是 Latency:監控事件優先級不同(崩潰 > 正常結束、溫度 > 磁碟滿)。
- 8 個 TCP 連線(Slave)+ 多 Client + Monitor 推播 + 異步 Log + DB 存取。
- 執行緒規劃(共 10 條,多於核心數但多數閒置,靠 OS 調度):
- 4 條 IO 執行緒處理 Slave 通訊
- 1 條 Logging 執行緒
- 1 條 DB IO 執行緒
- 2 條 Client 通訊 IO 執行緒
- 1 條主執行緒(排程、背景任務)
- 1 條 Pushing 執行緒(狀態廣播)
服務端執行緒三大分類
- IO 執行緒:主循環
epoll_wait,處理網路事件與定時器,可輕量計算。
- 計算執行緒:主循環阻塞隊列
condition_variable,位於執行緒池,處理耗 CPU 任務。
- 第三方庫執行緒:Logging、Database Connection Pool 內建執行緒,回調業務代碼。
服務啟動時一次性建立所有執行緒,運行期不動態創建/銷毀。
結語
多核時代多執行緒編程不可避免,「鴕鳥演算法」不可取。關鍵在於識別共享可變狀態、隔離優先級、異步化關鍵路徑,而非盲目追求並發度。