發表於2024-11-09
多年編寫生産環境下多綫程服務端程序經驗之精華,示範在多核時代采用現代C++編寫多綫程TCP網絡服務器的正規做法
《Linux多綫程服務端編程 使用muduoC++網絡庫》主要講述采用現代C++在x86-64Linux上編寫多綫程TCP網絡服務程序的主流常規技術,重點講解一種適應性較強的多綫程服務器的編程模型,即oneloopperthread。這是在Linux下以native語言編寫用戶態高性能網絡程序成熟的模式,掌握之後可順利地開發各類常見的服務端網絡應用程序。本書以muduo網絡庫為例,講解這種編程模型的使用方法及注意事項。
《Linux多綫程服務端編程 使用muduoC++網絡庫》的宗旨是貴精不貴多。掌握兩種基本的同步原語就可以滿足各種多綫程同步的功能需求,還能寫齣更易用的同步設施。掌握一種進程間通信方式和一種多綫程網絡編程模型就足以應對日常開發任務,編寫運行於公司內網環境的分布式服務係統。
陳碩,北京師範大學碩士,擅長C++ 多綫程網絡編程和實時分布式係統架構。曾在摩根士丹利IT 部門工作5 年,從事實時外匯交易係統開發。現在在美國加州矽榖某互聯網大公司工作,從事大規模分布式係統的可靠性工程。編寫瞭開源C++ 網絡庫muduo,參與翻譯瞭《代碼大全(第2 版)》和《C++ 編程規範(繁體版)》,整理瞭《C++ Primer (第4 版)(評注版)》,並曾多次在各地技術大會演講。
第1 部分 C++ 多綫程係統編程
第1 章 綫程安全的對象生命期管理
1.1 當析構函數遇到多綫程
1.1.1 綫程安全的定義
1.1.2 MutexLock 與MutexLockGuard
1.1.3 一個綫程安全的Counter 示例
1.2 對象的創建很簡單.
1.3 銷毀太難
1.3.1 mutex 不是辦法
1.3.2 作為數據成員的mutex 不能保護析構.
1.4 綫程安全的Observer 有多難.
1.5 原始指針有何不妥.
1.6 神器shared_ptr/weak_ptr
1.7 插麯:係統地避免各種指針錯誤.
1.8 應用到Observer 上
1.9 再論shared_ptr 的綫程安全.
1.10 shared_ptr 技術與陷阱
1.11 對象池.
1.11.1 enable_shared_from_this
1.11.2 弱迴調.
1.12 替代方案
1.13 心得與小結.
1.14 Observer 之謬.
第2 章 綫程同步精要
2.1 互斥器(mutex) .
2.1.1 隻使用非遞歸的mutex
2.1.2 死鎖
2.2 條件變量(condition variable) .
2.3 不要用讀寫鎖和信號量
2.4 封裝MutexLock、MutexLockGuard、Condition
2.5 綫程安全的Singleton 實現
2.6 sleep(3) 不是同步原語
2.7 歸納與總結.
2.8 藉shared_ptr 實現copy-on-write
第3 章 多綫程服務器的適用場閤與常用編程模型
3.1 進程與綫程.
3.2 單綫程服務器的常用編程模型
3.3 多綫程服務器的常用編程模型
3.3.1 one loop per thread
3.3.2 綫程池.
3.3.3 推薦模式
3.4 進程間通信隻用TCP .
3.5 多綫程服務器的適用場閤.
3.5.1 必須用單綫程的場閤.
3.5.2 單綫程程序的優缺點.
3.5.3 適用多綫程程序的場景
3.6 “多綫程服務器的適用場閤”例釋與答疑
第4 章 C++ 多綫程係統編程精要
4.1 基本綫程原語的選用.
4.2 C/C++ 係統庫的綫程安全性.
4.3 Linux 上的綫程標識
4.4 綫程的創建與銷毀的守則.
4.4.1 pthread_cancel 與C++ .
4.4.2 exit(3) 在C++ 中不是綫程安全的.
4.5 善用__thread 關鍵字.
4.6 多綫程與IO
4.7 用RAII 包裝文件描述符.
4.8 RAII 與fork() .
4.9 多綫程與fork() .
4.10 多綫程與signal
4.11 Linux 新增係統調用的啓示
第5 章 高效的多綫程日誌
5.1 功能需求
5.2 性能需求
5.3 多綫程異步日誌
5.4 其他方案
第2 部分 muduo 網絡庫
第6 章 muduo 網絡庫簡介
6.1 由來.
6.2 安裝.
6.3 目錄結構
6.3.1 代碼結構
6.3.2 例子
6.3.3 綫程模型
6.4 使用教程
6.4.1 TCP 網絡編程本質論.
6.4.2 echo 服務的實現.
6.4.3 七步實現finger 服務.
6.5 性能評測
6.5.1 muduo 與Boost.Asio、libevent2 的吞吐量對比
6.5.2 擊鼓傳花:對比muduo 與libevent2 的事件處理效率
6.5.3 muduo 與Nginx 的吞吐量對比.
6.5.4 muduo 與ZeroMQ 的延遲對比.
6.6 詳解muduo 多綫程模型.
6.6.1 數獨求解服務器
6.6.2 常見的並發網絡服務程序設計方案.
第7 章 muduo 編程示例
7.1 五個簡單TCP 示例
7.2 文件傳輸
7.3 Boost.Asio 的聊天服務器.
7.3.1 TCP 分包
7.3.2 消息格式
7.3.3 編解碼器LengthHeaderCodec
7.3.4 服務端的實現.
7.3.5 客戶端的實現.
7.4 muduo Buffer 類的設計與使用.
7.4.1 muduo 的IO 模型
7.4.2 為什麼non-blocking 網絡編程中應用層buffer 是必需的
7.4.3 Buffer 的功能需求
7.4.4 Buffer 的數據結構
7.4.5 Buffer 的操作.
7.4.6 其他設計方案.
7.4.7 性能是不是問題
7.5 一種自動反射消息類型的Google Protobuf 網絡傳輸方案
7.5.1 網絡編程中使用Protobuf 的兩個先決條件.
7.5.2 根據type name 反射自動創建Message 對象
7.5.3 Protobuf 傳輸格式
7.6 在muduo 中實現Protobuf 編解碼器與消息分發器
7.6.1 什麼是編解碼器(codec)
7.6.2 實現ProtobufCodec .
7.6.3 消息分發器(dispatcher)有什麼用
7.6.4 ProtobufCodec 與ProtobufDispatcher 的綜閤運用.
7.6.5 ProtobufDispatcher 的兩種實現
7.6.6 ProtobufCodec 和ProtobufDispatcher 有何意義.
7.7 限製服務器的最大並發連接數
7.7.1 為什麼要限製並發連接數
7.7.2 在muduo 中限製並發連接數
7.8 定時器.
7.8.1 程序中的時間.
7.8.2 Linux 時間函數
7.8.3 muduo 的定時器接口.
7.8.4 Boost.Asio Timer 示例
7.8.5 Java Netty 示例
7.9 測量兩颱機器的網絡延遲和時間差.
7.10 用timing wheel 踢掉空閑連接
7.10.1 timing wheel 原理
7.10.2 代碼實現與改進
7.11 簡單的消息廣播服務.
7.12 “串並轉換”連接服務器及其自動化測試
7.13 socks4a 代理服務器
7.13.1 TCP 中繼器
7.13.2 socks4a 代理服務器
7.13.3 N : 1 與1 : N 連接轉發
7.14 短址服務
7.15 與其他庫集成.
7.15.1 UDNS .
7.15.2 c-ares DNS .
7.15.3 curl .
7.15.4 更多
第8 章 muduo 網絡庫設計與實現
8.0 什麼都不做的EventLoop .
8.1 Reactor 的關鍵結構
8.1.1 Channel class .
8.1.2 Poller class
8.1.3 EventLoop 的改動.
8.2 TimerQueue 定時器
8.2.1 TimerQueue class .
8.2.2 EventLoop 的改動.
8.3 EventLoop::runInLoop() 函數
8.3.1 提高TimerQueue 的綫程安全性.
8.3.2 EventLoopThread class
8.4 實現TCP 網絡庫
8.5 TcpServer 接受新連接
8.5.1 TcpServer class
8.5.2 TcpConnection class .
8.6 TcpConnection 斷開連接.
8.7 Buffer 讀取數據
8.7.1 TcpConnection 使用Buffer 作為輸入緩衝.
8.7.2 Buffer::readFd()
8.8 TcpConnection 發送數據.
8.9 完善TcpConnection
8.9.1 SIGPIPE
8.9.2 TCP No Delay 和TCP keepalive
8.9.3 WriteCompleteCallback 和HighWaterMarkCallback .
8.10 多綫程TcpServer .
8.11 Connector .
8.12 TcpClient .
8.13 epoll
8.14 測試程序一覽.
第3 部分 工程實踐經驗談
第9 章 分布式係統工程實踐
9.1 我們在技術浪潮中的位置.
9.1.1 分布式係統的本質睏難
9.1.2 分布式係統是個險惡的問題.
9.2 分布式係統的可靠性淺說.
9.2.1 分布式係統的軟件不要求7 24 可靠
9.2.2 “能隨時重啓進程”作為程序設計目標.
9.3 分布式係統中心跳協議的設計
9.4 分布式係統中的進程標識.
9.4.1 錯誤做法
9.4.2 正確做法
9.4.3 TCP 協議的啓示
9.5 構建易於維護的分布式程序.
9.6 為係統演化做準備.
9.6.1 可擴展的消息格式
9.6.2 反麵教材:ICE 的消息打包格式.
9.7 分布式程序的自動化迴歸測試
9.7.1 單元測試的能與不能.
9.7.2 分布式係統測試的要點
9.7.3 分布式係統的抽象觀點
9.7.4 一種自動化的迴歸測試方案.
9.7.5 其他用處
9.8 分布式係統部署、監控與進程管理的幾重境界.
9.8.1 境界1:全手工操作.
9.8.2 境界2:使用零散的自動化腳本和第三方組件.
9.8.3 境界3:自製機群管理係統,集中化配置.
9.8.4 境界4:機群管理與naming service 結閤.
第10 章 C++ 編譯鏈接模型精要
10.1 C 語言的編譯模型及其成因.
10.1.1 為什麼C 語言需要預處理
10.1.2 C 語言的編譯模型.
10.2 C++ 的編譯模型
10.2.1 單遍編譯
10.2.2 前嚮聲明
10.3 C++ 鏈接(linking) .
10.3.1 函數重載
10.3.2 inline 函數.
10.3.3 模闆
10.3.4 虛函數.
10.4 工程項目中頭文件的使用規則
10.4.1 頭文件的害處.
10.4.2 頭文件的使用規則
10.5 工程項目中庫文件的組織原則
10.5.1 動態庫是有害的
10.5.2 靜態庫也好不到哪兒去
10.5.3 源碼編譯是王道
第11 章 反思C++ 麵嚮對象與虛函數
11.1 樸實的C++ 設計
11.2 程序庫的二進製兼容性
11.2.1 什麼是二進製兼容性.
11.2.2 有哪些情況會破壞庫的ABI .
11.2.3 哪些做法多半是安全的
11.2.4 反麵教材:COM .
11.2.5 解決辦法
11.3 避免使用虛函數作為庫的接口
11.3.1 C++ 程序庫的作者的生存環境
11.3.2 虛函數作為庫的接口的兩大用途
11.3.3 虛函數作為接口的弊端
11.3.4 假如Linux 係統調用以COM 接口方式實現
11.3.5 Java 是如何應對的
11.4 動態庫接口的推薦做法
11.5 以boost::function 和boost::bind 取代虛函數.
11.5.1 基本用途
11.5.2 對程序庫的影響
11.5.3 對麵嚮對象程序設計的影響.
11.6 iostream 的用途與局限
11.6.1 stdio 格式化輸入輸齣的缺點.
11.6.2 iostream 的設計初衷.
11.6.3 iostream 與標準庫其他組件的交互.
11.6.4 iostream 在使用方麵的缺點.
11.6.5 iostream 在設計方麵的缺點.
11.6.6 一個300 行的memory buffer output stream .
11.6.7 現實的C++ 程序如何做文件IO .
11.7 值語義與數據抽象.
11.7.1 什麼是值語義.
11.7.2 值語義與生命期
11.7.3 值語義與標準庫
11.7.4 值語義與C++ 語言
11.7.5 什麼是數據抽象
11.7.6 數據抽象所需的語言設施
11.7.7 數據抽象的例子
第12 章 C++ 經驗談
12.1 用異或來交換變量是錯誤的.
12.1.1 編譯器會分彆生成什麼代碼.
12.1.2 為什麼短的代碼不一定快
12.2 不要重載全局::operator new()
12.2.1 內存管理的基本要求.
12.2.2 重載::operator new() 的理由.
12.2.3 ::operator new() 的兩種重載方式.
12.2.4 現實的開發環境
12.2.5 重載::operator new() 的睏境.
12.2.6 解決辦法:替換malloc()
12.2.7 為單獨的class 重載::operator new() 有問題嗎.
12.2.8 有必要自行定製內存分配器嗎
12.3 帶符號整數的除法與餘數.
12.3.1 語言標準怎麼說
12.3.2 C/C++ 編譯器的錶現.
12.3.3 其他語言的規定
12.3.4 腳本語言解釋器代碼.
12.3.5 硬件實現
12.4 在單元測試中mock 係統調用
12.4.1 係統函數的依賴注入.
12.4.2 鏈接期墊片(link seam)
12.5 慎用匿名namespace .
12.5.1 C 語言的static 關鍵字的兩種用法.
12.5.2 C++ 語言的static 關鍵字的四種用法
12.5.3 匿名namespace 的不利之處.
12.5.4 替代辦法
12.6 采用有利於版本管理的代碼格式.
12.6.1 對diff 友好的代碼格式
12.6.2 對grep 友好的代碼風格.
12.6.3 一切為瞭效率.
12.7 再探std::string .
12.7.1 直接拷貝(eager copy) .
12.7.2 寫時復製(copy-on-write) .
12.7.3 短字符串優化(SSO)
12.8 用STL algorithm 輕鬆解決幾道算法麵試題
12.8.1 用next_permutation() 生成排列與組閤
12.8.2 用unique() 去除連續重復空白.
12.8.3 用{make,push,pop}_heap() 實現多路歸並
12.8.4 用partition() 實現“重排數組,讓奇數位於偶數前麵”
12.8.5 用lower_bound() 查找IP 地址所屬的城市.
第4 部分 附錄
附錄A 談一談網絡編程學習經驗
附錄B 從《C++ Primer(第4 版)》入手學習C++
附錄C 關於Boost 的看法
附錄D 關於TCP 並發連接的幾個思考題與試驗
附錄A
談一談網絡編程學習經驗
本文談一談我在學習網絡編程方麵的一些個人經驗。“網絡編程”這個術語的範圍很廣,本文指用Sockets API 開發基於TCP/IP 的網絡應用程序,具體定義見§A.1.5 “網絡編程的各種任務角色”。
受限於本人的經曆和經驗,本附錄的適應範圍是:
x86-64 Linux 服務端網絡編程,直接或間接使用Sockets API。
公司內網。不一定是局域網,但總體位於公司防火牆之內,環境可控。
本文可能不適閤:
PC 客戶端網絡編程,程序運行在客戶的PC 上,環境多變且不可控。
Windows 網絡編程。
麵嚮公網的服務程序。
高性能網絡服務器。
本文分兩個部分:
1. 網絡編程的一些“鬍思亂想”,以自問自答的形式談談我對這一領域的認識。
2. 幾本必看的書,基本上還是W. Richard Stevents 的那幾本。
另外,本文沒有特彆說明時均暗指TCP 協議,“連接”是“TCP 連接”,“服務
端”是“TCP 服務端”。
A.1 網絡編程的一些“鬍思亂想”
以下大緻列齣我對網絡編程的一些想法,前後無關聯。
A.1.1 網絡編程是什麼
網絡編程是什麼?是熟練使用Sockets API 嗎?說實話,在實際項目裏我隻用過
兩次Sockets API,其他時候都是使用封裝好的網絡庫。
第一次是2005 年在學校做一個羽毛球賽場計分係統:我用C# 編寫運行在PC上的軟件,負責比分的顯示;再用C# 寫瞭運行在PDA 上的計分界麵,記分員拿著PDA 記錄比分;這兩部分程序通過TCP 協議相互通信。這其實是個簡單的分布式係統,體育館有幾片場地,每個場地都有一名拿PDA 的記分員,每個場地都有兩颱顯示比分的PC (顯示器是42 寸平闆電視,放在場地的對角,這樣兩邊看颱的觀眾都能看到比分)。這兩颱PC 的功能不完全一樣,一颱隻負責顯示當前比分,另一颱還要負責與PDA 通信,並更新數據庫裏的比分信息。此外,還有一颱PC 負責周期性地從數據庫讀齣全部7 片場地的比分,顯示在體育館牆上的大屏幕上。這颱PC 上還運行
Linux多綫程服務端編程 使用muduo C++網絡庫 下載 mobi epub pdf txt 電子書 格式
Linux多綫程服務端編程 使用muduo C++網絡庫 下載 mobi pdf epub txt 電子書 格式 2024
Linux多綫程服務端編程 使用muduo C++網絡庫 下載 mobi epub pdf 電子書好,看著不錯!!!!!!!
評分恍恍惚惚恍恍惚惚哈哈哈
評分很不錯的書,網絡編程進階必備參考書籍。值得好好學習一下瞭。
評分好,看著不錯!!!!!!!
評分書應該是正版,還沒有看
評分需要一定基礎。
評分bnhhhhkmjjjjjkk
評分質量挺好的,隔天就到,京東一如既往靠譜。
評分你能體會到從這一麵能看到對麵的文字嗎?看起來就像一團亂麻。還有一些地方,墨直接被抹掉瞭,字完全看不清,雖然不是每一頁都有問題,但是完全影響心情啊。完全不值這麼多錢。
Linux多綫程服務端編程 使用muduo C++網絡庫 mobi epub pdf txt 電子書 格式下載 2024