预购商品
书目分类
特别推荐
本書專注於簡單容易了解的程式碼,以及最接近C語言的語法,並且大量應用多執行緒的思路,開發出來的非阻塞式(Non-blocking)網路程式庫,比同級產品快了20%,程式碼卻少了50%,充份展現C++的小而美且快。除了C++之外,本書亦充份介紹目前Scale out網路架構的概念,讓你不但可快速學會C++的網路開發,更可了解目前最新的雲端趨勢。 想學好C++就從全球第一個華人開發的頂級C++網路程式庫Muduo開始。本書主要說明採用現代C++ 在x86-64 Linux 上撰寫多執行緒TCP 網路服務程式的主流標準技術,重點說明多執行緒網路服務器的一種IO 模型,即one loopper thread。這是一種適應性強的模型,也是Linux 下以native 語言撰寫使用者態高性能網路程式最成熟的模式,熟練之後可順利地開發各種常見的服務端網路應用程式。本書以muduo 網路函數庫為例,說明這種程式設計模型的使用方法及注意事項。 C++學習時間長,一旦上手,開發出程式碼的超高速度是Java、C#等其它語言無法比較的。
第1 部分 C++ 多執行緒系統程式設計 Chapter 01 符合執行緒安全的物件生命期管理 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 之謬 Chapter 02 執行緒同步精要 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 Chapter 02 多執行緒伺服器的適用場合與常用程式設計模型 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 「多執行緒伺服器的適用場合」例釋與答疑 Chapter 04 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 新增系統呼叫的啟示 Chapter 05 高效的多執行緒記錄檔 5.1 功能需求 5.2 效能需求 5.3 多執行緒非同步記錄檔 5.4 其他方案 第2 部分 muduo 網路函數庫 Chapter 06 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 常見的平行處理網路服務程式設計方案 Chapter 07 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 一種自動反射訊息類型的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 更多 Chapter 08 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 部分 專案實作經驗談 Chapter 09 分散式系統專案實作 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 結合 Chapter 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 原始程式編譯是王道 Chapter 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 資料抽象的實例 Chapter 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 指令碼語言解譯器程式0 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部分 附錄 Appendix A 談一談網路程式設計學習經驗 A.1 網路程式設計的一些「胡思亂想」 A.1.1 網路程式設計是什麼 A.1.2 學習網路程式設計有用嗎 A.1.3 在什麼平台上學習網路程式設計 A.1.4 可攜性重要嗎 A.1.5 網路程式設計的各種工作角色 A.1.6 針對業務的網路程式設計的特點 A.1.7 幾個術語 A.1.8 7×24 重要嗎,記憶體碎片可怕嗎 A.1.9 協定設計是網路程式設計的核心 A.1.10 網路程式設計的三個層次 A.1.11 最主要的三個實例 A.1.12 學習Sockets API 的利器:IPython A.1.13 TCP 的可用性有多高 A.2 三本必看的書 Appendix B 從《C++ Primer(第4 版)》入手學習C++ B.1 為什麼要學習C++ B.2 學習C++只需要讀一本大部頭 B.3 繼續前進 B.4 評注版使用說明 Appendix C 關於Boost 的看法 Appendix D關於 TCP 平行處理連接的幾個思考題與試驗
作者簡介 陳碩 北京師範大學碩士,擅長C++多執行緒網路程式設計和即時分散式系統架構。曾在摩根史丹利IT部門工作5年,從事即時外匯交易系統開發。現在在美國加州矽谷某互聯網大公司工作,從事大規模分散式系統的可靠性工程。
最近浏览商品
客服公告
热门活动
订阅电子报