首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

Muduo 多線程模型實戰:從單線程到多 Reactor 的 Sudoku 服務器演進

     編輯:關於C++

背景與目標

以 Sudoku Solver 為例,展示並發網絡服務的多種架構演進,重點介紹 Muduo 庫內建的兩種多線程模式:Thread Pool(方案 8) 與 Multiple Reactors / One Loop Per Thread(方案 9)。

協議設計

  • 文本行協議,\r\n 分隔,TCP 長連接。
  • 請求:[id:]<81 digits>\r\n(id 選擇性,支援 Pipeline)。
  • 回應:[id:]<81 digits>\r\n 或 [id:]NoSolution\r\n。

基礎單線程版

核心邏輯在 onMessage 解析協議、呼叫 solveSudoku(純函式、線程安全),再 send 回覆。完整代碼見 server_basic.cc。單線程無法利用多核。

十大經典並發方案對比

參考 UNP CSDA 與陳碩總結,關鍵指標:

  • fork()+exit():160 µs
  • pthread_create+join:12 µs
  • 上下文切換:1.5 µs
  • Sudoku 求解:~100 µs(20~200 µs)
方案模型優點缺點
0Iterative簡單一次只服務一個客戶
1Process per Connection隔離性好fork 開銷大,不適合短連接
2Thread per Connection開銷較小線程數受限,數千連接壓垮調度器
5單線程 ReactorIO 密集型極佳CPU 密集型無法發揮多核
6每請求一線程利用多核頻繁建線程,Out-of-order
7每連接一計算線程保序連接數受限於線程數
8Reactor + Thread PoolIO/計算分離,固定線程池兩次上下文切換,Out-of-order
9Multiple ReactorsOne loop per thread,減少切換,保序單連接突發計算受限單核
10混合模式兼顧 IO 與計算突發實現較複雜

方案 8:Reactor + Thread Pool 實作

主 Reactor 負責 IO,計算任務丟給 ThreadPool。關鍵差異:

// server_threadpool.cc 片段
threadPool_.run(boost::bind(solve, conn, request, id)); // 交給線程池

static void solve(const TcpConnectionPtr& conn, const string& req, const string& id) {
    string result = solveSudoku(req);
    conn->send(id.empty() ? result+"\r\n" : id+":"+result+"\r\n");
}

注意:此模式可能 Out-of-order,客戶端需靠 id 匹配。

方案 9:Multiple Reactors(Muduo 預設)

一個 mainReactor 负責 accept,採 Round-robin 分派連接到多個 subReactor(各自一線程)。連接生命周期完全在該線程,天然保序、無額外切換。

代碼差異極小:

server_.setThreadNum(numThreads); // 單行啟用多線程

diff server_basic.cc server_multiloop.cc 僅增加構造函數參數與該行。

方案 10:混合模式

在方案 9 基礎上再加 server_.setThreadNum(numThreads) 並保留 ThreadPool,適合同時有 IO 突發與計算突發的場景。

結語

推薦模式:Event Loop Per Thread + Thread Pool。Muduo 將這一思想封裝為開箱即用的 TcpServer::setThreadNum(),讓開發者專注業務邏輯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved