• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            陳碩的Blog

            《Linux多線程服務端編程:使用muduo C++網絡庫》上市半年重印兩次,總印數達到了9000冊

            《Linux多線程服務端編程:使用muduo C++網絡庫》這本書自今年一月上市以來,半年之內已經重印兩次(加上首印,一共是三次印刷),總印數達到了9000冊,這在技術書里已經算是相當不錯的成績。本書購買方式見配套網站 http://chenshuo.com/book

            以下談一談這本書的寫作背景與內容取舍的原因。

            參加工作以來,我編寫并維護了若干C++/Java多線程網絡服務程序,這本書總結了我在開發維護這類服務程序方面的經驗。工作中,我沒有寫過單線程的網絡服務程序,沒有寫過C語言的網絡服務程序,也沒有寫過運行在Windows下的網絡服務程序,因此本書不涉及這些內容。

            在“Linux服務端開發”這一背景下,這本書主要講三個方面的內容[1]:現代C++、多線程、網絡編程,分別對應書的第3、1、2部分。這不是一本入門書,本書的讀者應該在以上三方面已經具備相當的基礎[2]:網絡編程方面,能輕松讀懂6.1節的兩個Python程序;C++方面,對12.8節的代碼不感到陌生;多線程方面,能明白第1章要解決什么問題。

            第9章“分布式系統工程實踐”詳細介紹了這本書的應用背景,即開發公司內部的分布式服務系統,書中的很多決策(design decision)和技術取舍(trade-off)是在這一應用場景下做出的。以下是各章直接的交叉引用關系圖(沒有計算引用次數),其中第0章是前言,字母章節是附錄。可見第9章是被引用最多的一章,某種意義上可以說第9章既是本書的先決條件,又是本書的終極目標。由于章節之間存在眾多的交叉引用,去掉任何一章都會破壞內容的完整性。

            ref

            這本書的書名原本打算叫“Linux C++ 多線程系統編程”。寫完之后發現,與其他Unix/Linux系統編程方面的書不同,這本書有明確的應用場景,因此可以砍掉很多內容,突出重點。甚至可以說我主要講別的書沒有講到的內容。這不是一本面面俱到的書,因此最終的書名也就不叫“系統編程”了。

            同時,我認為很多教科書上介紹的一些做法是過時的(signal),一些是不推薦使用的(從外部終止線程、TCP OOB數據),一些是大多數情況下沒必要使用的(內存池、lock-free 編程)。作為全面的教材和手冊,把這些內容放進去可以理解。但是這本書定位是經驗總結,我略去了教科書上那些基本用不到的知識點,以免喧賓奪主,也建議讀者不要把精力花在那些次要問題上。

            • 這本書沒有花很大的篇幅去講signal,而是在第4.10節說明多線程程序不要使用signal作為IPC。并且,在muduo-protorpc的示例中給出了Linux專有的signalfd(2)的用法,可以避免傳統signal handler的常見陷阱,也更符合UNIX的“everything is a file”哲學。第4.4節說明不要從外部終止線程,因此也就不必去細究Pthreads cancellation point了。多線程程序最好不要fork()(第4.9節)。
            • 這本書沒介紹daemon進程,我認為daemon是過時的做法。因為daemon進程的父進程是init(1),配置文件在本機,不便于多機統一監控與管理(第9.8節)。(注:如果是第三方標準的服務程序,又不需要經常升級或改配置重啟,并且一旦崩潰,重啟就能繼續服務,那么做成 daemon 讓init(1)接管是可以的,比如ntpd、sshd等。這里談的是自己開發維護的服務程序。)另外,Java/Python/Go寫的服務程序似乎也沒有做成daemon的習慣,C++程序沒有理由要特殊對待。補充一點,Linux的進程管理機制很落后(從UNIX繼承而來),子進程退出的事件只能被父進程以SIGCHLD信號的方式收到(而且這個signal可能丟失),kill(pid) 也存在很多race condition(你怎么保證pid在kill之前的一瞬間還代表你想kill的那個進程,而不是一個新啟動的進程?close(fd)就不會有這種 race condition。)。這些困難在用戶態無法克服,只能修改內核,引入新的系統調用才能治本。例如 FreeBSD 9.0 引入了 pdfork()/pdkill() 等,將子進程變成文件描述符,這樣就能用IO事件框架統一處理了,也符合UNIX的“everything is a file”哲學。但愿Linux內核也能盡快引入類似的系統調用,減輕程序員的負擔。
            • 這本書沒有講內存池,而是說明不是每個程序都要自己寫內存池(§12.2.8)。這本書也沒有把“避免內存碎片”掛在嘴邊,而是論證為什么一般的程序不必在意它(§A.1.8);
            • 這本書只關注Linux,不考慮移植性。它推薦使用Linux專有的gettid()系統調用作為線程標識(第4.3節),而不是用pthread_self()。
            • 這本書不講POSIX中五花八門的定時函數,而專講用Linux特有的timerfd來實現高精度定時(§7.8.2),因為它能方便地融入IO事件處理框架。muduo直接使用C++標準庫來管理定時器,而不是自己實現小頂堆(heap),這樣可以簡化實現(§8.2.1)。
            • 這本書只講mutex和condition variable作為最基礎的線程同步手段(第2章),并且我認為一個C++多線程程序代碼里不應該直接出現pthread_mutex_lock之類的基本Pthreads調用。本書進一步建議只使用非遞歸的mutex(§2.1.1),這與某些網上文章的推薦正好相反。這本書第2.3節甚至建議不要使用讀寫鎖和信號量(semaphore),因為一是容易用錯,二是不見得能提高性能。mutex和condition variable是完備的,能實現多種更易用的同步設施,例如CountDownLatch和BlockingQueue。§12.8.3的代碼展示了用BlockingQueue和ThreadPool控制并發度的手法,做到了“No locks. No condition variables. No callbacks.”
            • 這本書不講lock-free編程,因為編寫可靠的lock-free代碼并分析驗證其正確性的難度遠大于編寫普通的使用mutex和condition variable的多線程代碼,后者已經有了相當成熟的理論和工具。我認為lock-free不是每個多線程程序員應該掌握的技術,它投入高而用處少,可以適當了解,但不值得每個人都去深究。只需要少數人用它實現封裝好的數據結構,像我這樣的普通人就可以受益。
            • 這本書只講BSD Sockets作為進程間通信的手段,并且只用TCP長連接(§3.4)。這樣就砍掉了pipe、FIFO、POSIX message queue、shared memory、STREAMS、UNIX domain socket等等內容,因為它們都只限本機進程間通信,無法擴展到多機。
            • 網絡編程方面(第6、7章),這本書不講Sockets API的基本用法,而且代碼中也不會直接使用它們。我認為在程序中直接使用 Sockets API是初學者的做法,當寫一個新網絡服務程序,如果一開始考慮的是怎么組織accept、read、epoll_wait等調用,這種做法無異于用鉛筆刀鋸大樹,事倍功半,也不利于將來的功能擴展和維護。稍微像樣點的公司都會用成熟的網絡庫(不一定開源),把網絡編程的復雜性封裝進去,暴露出良好易用的接口,讓開發人員使用更高層的building blocks(消息傳遞或RPC)從功能的角度去設計程序,避免一次次反復掉到TCP網絡編程的坑里。多個服務程序共享相同的基礎庫和事件處理框架的益處是顯而易見的,一方面把網絡編程的復雜性集中到一起,避免每個團隊都去踏一遍坑;另一方面,基礎庫的bug修復與性能優化能惠及用到它的全部服務程序;最后,程序結構上的相似性讓編程經驗更加通用,多個服務程序在功能、性能、正確性等方面具有共性,能舉一反三觸類旁通,降低將來開發維護的成本。應該避免每個程序都另起爐灶,單獨設計其IO事件處理結構。
            • 這本書只講非阻塞IO結合IO復用(IO-Multiplexing)這一種并發風格(歸納為三個半事件),并介紹在多線程下的擴展(one loop per thread)。IO復用方面,本書只講level-trigger,不講edge-trigger。一方面目前沒有up to date的測試表明ET更快,相反,我認為LT在讀取數據時可以節約一次read()調用(§8.7.2);另一方面,LT模式更容易與其他第三方庫結合(§7.15)。多線程程序管理并發socket fd有很多風格可供選擇,例如epoll fd是多個線程共享一個(多對一)還是每個線程有自己的epoll fd(一對一),每個socket fd是只屬于一個epoll fd(多對一)還是可以同時屬于多個 epoll fd(多對多),每個socket fd是只能被固定的一個線程讀寫還是可以被多個線程讀寫(如果是后者,那么讀寫的時候是加鎖還是使用ONESHOT)。以上不是每種都可行,本書也沒有一一加以分析,而是建議使用one loop per thread這種適用性較強的風格,首先是正確性容易驗證,其次是性能也能滿足要求。
            • 本書不講IPv6,因為目前世界上最大的公司的服務機群也用不完一個私有A類地址(10.0.0.0/8)。本書不講UDP,因為《Unix網絡編程》已經講得很好了。
            • 這本書舉的網絡編程的例子不再是簡單的echo服務,而是有格式(因此引入codec)、多連接之間會交換數據的網絡程序,更接近業務場景,也借機講解如何避免TCP網絡編程的常見陷阱。并且在示例代碼中給出了分布式單詞計數、多機求中位數等稍微復雜一點的程序。
            • 在C++方面,這本書沒有介紹動態鏈接庫熱更新這種“高級”技術,而是說明,在分布式系統中,為了部署方便,應該從源碼編譯全部的庫,與主程序鏈接為一個standalone的可執行文件,以減小對運行環境的依賴(第10章)。第11章還討論了程序庫與應用程序之間的接口設計。

            “信息”按照香農的定義,是“減少不確定性”,這本書包含的信息正是減少選用編程設施(facilities)方面的不確定性,讓讀者集中精力攻克本質問題。這本書介紹的方法不一定對于每個應用場景都是最好的,但肯定是簡便易行的,是時間成本、功能、性能的一種合理折中。


            [1] 這本書前言的第一句話“本書主要講述采用現代 C++ 在 x86-64 Linux 上編寫多線程 TCP 網絡服務程序的主流常規技術”,封面印著“示范在多核時代采用現代 C++ 編寫多線程 TCP 網絡服務器的正規做法”。

            [2] 前言寫到:讀者應該已經大致讀過《現代操作系統》、《UNIX 環境高級編程》、《UNIX 網絡編程》、《C++ Primer》或與之內容相近的書籍,熟悉基本概念,并掌握 Pthreads 和 Sockets API 的常規用法。

            posted on 2013-07-17 11:17 陳碩 閱讀(2576) 評論(3)  編輯 收藏 引用

            評論

            # re: 《Linux多線程服務端編程:使用muduo C++網絡庫》上市半年重印兩次,總印數達到了9000冊 2013-07-18 17:34 苗永超

            我主要看了這本書的第一部分和第三部分~  回復  更多評論   

            # re: 《Linux多線程服務端編程:使用muduo C++網絡庫》上市半年重印兩次,總印數達到了9000冊 2013-07-18 20:25 matrixj

            用了三個星期幾乎完整得看了一遍,有種豁然開朗的感覺,,覺得自己在實踐上的經驗知識太少了,這本書正好補上了這一點,非常不錯的書。  回復  更多評論   

            # re: 《Linux多線程服務端編程:使用muduo C++網絡庫》上市半年重印兩次,總印數達到了9000冊 2013-07-23 17:01 tb

            非常有用的   回復  更多評論   

            <2013年8月>
            28293031123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            導航

            統計

            常用鏈接

            隨筆分類

            隨筆檔案

            相冊

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            综合久久精品色| 国产AV影片久久久久久| 久久人人爽人人爽人人片AV不| 99久久免费国产精品特黄| 99精品国产综合久久久久五月天| 人妻久久久一区二区三区| 99久久无码一区人妻a黑| 久久久久国色AV免费观看| 亚洲AV无码成人网站久久精品大| 国产成人精品免费久久久久| 久久996热精品xxxx| 色欲av伊人久久大香线蕉影院| 91精品国产综合久久四虎久久无码一级| 久久黄视频| 丁香五月网久久综合| 国产精品久久久久蜜芽| 国产精品亚洲美女久久久| 色88久久久久高潮综合影院| 人人狠狠综合久久亚洲| 久久综合丁香激情久久| 久久精品国产亚洲77777| 亚洲精品国产自在久久| 国产精品成人99久久久久91gav| 精品人妻伦九区久久AAA片69| 91久久福利国产成人精品| 久久久久久毛片免费播放| 性高湖久久久久久久久AAAAA| 大美女久久久久久j久久| 久久精品国产亚洲AV麻豆网站 | 2022年国产精品久久久久| 亚洲国产成人久久综合碰| 亚洲国产精品久久久久久| 99久久久精品| 国产精品久久久久久| 久久久av波多野一区二区| 久久亚洲精精品中文字幕| 亚洲精品美女久久777777| 精品久久亚洲中文无码| 色欲久久久天天天综合网精品 | 欧美激情精品久久久久久久九九九| 久久免费美女视频|