• <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多線(xiàn)程服務(wù)端編程:使用muduo C++網(wǎng)絡(luò)庫(kù)》上市半年重印兩次,總印數(shù)達(dá)到了9000冊(cè)

            《Linux多線(xiàn)程服務(wù)端編程:使用muduo C++網(wǎng)絡(luò)庫(kù)》這本書(shū)自今年一月上市以來(lái),半年之內(nèi)已經(jīng)重印兩次(加上首印,一共是三次印刷),總印數(shù)達(dá)到了9000冊(cè),這在技術(shù)書(shū)里已經(jīng)算是相當(dāng)不錯(cuò)的成績(jī)。本書(shū)購(gòu)買(mǎi)方式見(jiàn)配套網(wǎng)站 http://chenshuo.com/book

            以下談一談這本書(shū)的寫(xiě)作背景與內(nèi)容取舍的原因。

            參加工作以來(lái),我編寫(xiě)并維護(hù)了若干C++/Java多線(xiàn)程網(wǎng)絡(luò)服務(wù)程序,這本書(shū)總結(jié)了我在開(kāi)發(fā)維護(hù)這類(lèi)服務(wù)程序方面的經(jīng)驗(yàn)。工作中,我沒(méi)有寫(xiě)過(guò)單線(xiàn)程的網(wǎng)絡(luò)服務(wù)程序,沒(méi)有寫(xiě)過(guò)C語(yǔ)言的網(wǎng)絡(luò)服務(wù)程序,也沒(méi)有寫(xiě)過(guò)運(yùn)行在Windows下的網(wǎng)絡(luò)服務(wù)程序,因此本書(shū)不涉及這些內(nèi)容。

            在“Linux服務(wù)端開(kāi)發(fā)”這一背景下,這本書(shū)主要講三個(gè)方面的內(nèi)容[1]:現(xiàn)代C++、多線(xiàn)程、網(wǎng)絡(luò)編程,分別對(duì)應(yīng)書(shū)的第3、1、2部分。這不是一本入門(mén)書(shū),本書(shū)的讀者應(yīng)該在以上三方面已經(jīng)具備相當(dāng)?shù)幕A(chǔ)[2]:網(wǎng)絡(luò)編程方面,能輕松讀懂6.1節(jié)的兩個(gè)Python程序;C++方面,對(duì)12.8節(jié)的代碼不感到陌生;多線(xiàn)程方面,能明白第1章要解決什么問(wèn)題。

            第9章“分布式系統(tǒng)工程實(shí)踐”詳細(xì)介紹了這本書(shū)的應(yīng)用背景,即開(kāi)發(fā)公司內(nèi)部的分布式服務(wù)系統(tǒng),書(shū)中的很多決策(design decision)和技術(shù)取舍(trade-off)是在這一應(yīng)用場(chǎng)景下做出的。以下是各章直接的交叉引用關(guān)系圖(沒(méi)有計(jì)算引用次數(shù)),其中第0章是前言,字母章節(jié)是附錄。可見(jiàn)第9章是被引用最多的一章,某種意義上可以說(shuō)第9章既是本書(shū)的先決條件,又是本書(shū)的終極目標(biāo)。由于章節(jié)之間存在眾多的交叉引用,去掉任何一章都會(huì)破壞內(nèi)容的完整性。

            ref

            這本書(shū)的書(shū)名原本打算叫“Linux C++ 多線(xiàn)程系統(tǒng)編程”。寫(xiě)完之后發(fā)現(xiàn),與其他Unix/Linux系統(tǒng)編程方面的書(shū)不同,這本書(shū)有明確的應(yīng)用場(chǎng)景,因此可以砍掉很多內(nèi)容,突出重點(diǎn)。甚至可以說(shuō)我主要講別的書(shū)沒(méi)有講到的內(nèi)容。這不是一本面面俱到的書(shū),因此最終的書(shū)名也就不叫“系統(tǒng)編程”了。

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

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

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


            [1] 這本書(shū)前言的第一句話(huà)“本書(shū)主要講述采用現(xiàn)代 C++ 在 x86-64 Linux 上編寫(xiě)多線(xiàn)程 TCP 網(wǎng)絡(luò)服務(wù)程序的主流常規(guī)技術(shù)”,封面印著“示范在多核時(shí)代采用現(xiàn)代 C++ 編寫(xiě)多線(xiàn)程 TCP 網(wǎng)絡(luò)服務(wù)器的正規(guī)做法”。

            [2] 前言寫(xiě)到:讀者應(yīng)該已經(jīng)大致讀過(guò)《現(xiàn)代操作系統(tǒng)》、《UNIX 環(huán)境高級(jí)編程》、《UNIX 網(wǎng)絡(luò)編程》、《C++ Primer》或與之內(nèi)容相近的書(shū)籍,熟悉基本概念,并掌握 Pthreads 和 Sockets API 的常規(guī)用法。

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

            評(píng)論

            # re: 《Linux多線(xiàn)程服務(wù)端編程:使用muduo C++網(wǎng)絡(luò)庫(kù)》上市半年重印兩次,總印數(shù)達(dá)到了9000冊(cè) 2013-07-18 17:34 苗永超

            我主要看了這本書(shū)的第一部分和第三部分~  回復(fù)  更多評(píng)論   

            # re: 《Linux多線(xiàn)程服務(wù)端編程:使用muduo C++網(wǎng)絡(luò)庫(kù)》上市半年重印兩次,總印數(shù)達(dá)到了9000冊(cè) 2013-07-18 20:25 matrixj

            用了三個(gè)星期幾乎完整得看了一遍,有種豁然開(kāi)朗的感覺(jué),,覺(jué)得自己在實(shí)踐上的經(jīng)驗(yàn)知識(shí)太少了,這本書(shū)正好補(bǔ)上了這一點(diǎn),非常不錯(cuò)的書(shū)。  回復(fù)  更多評(píng)論   

            # re: 《Linux多線(xiàn)程服務(wù)端編程:使用muduo C++網(wǎng)絡(luò)庫(kù)》上市半年重印兩次,總印數(shù)達(dá)到了9000冊(cè) 2013-07-23 17:01 tb

            非常有用的   回復(fù)  更多評(píng)論   


            只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            <2014年12月>
            30123456
            78910111213
            14151617181920
            21222324252627
            28293031123
            45678910

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(lèi)

            隨筆檔案

            相冊(cè)

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            久久综合给合久久国产免费| 99久久精品国产高清一区二区| 97久久精品人人做人人爽| 久久综合色区| 久久久久99这里有精品10| 久久久一本精品99久久精品88| 久久免费的精品国产V∧| 国产综合成人久久大片91| 噜噜噜色噜噜噜久久| 久久精品国产精品青草app| 精品水蜜桃久久久久久久| 久久亚洲中文字幕精品有坂深雪| 久久伊人精品青青草原高清| 中文字幕无码久久久| 91精品国产色综久久| 99久久夜色精品国产网站| 91精品国产91久久久久久青草 | 亚洲中文字幕无码久久精品1| 久久久久久综合一区中文字幕| 久久精品综合网| 久久er国产精品免费观看8| 久久精品中文騷妇女内射| 亚洲欧美国产精品专区久久 | 日本精品久久久久影院日本| 三上悠亚久久精品| 欧美伊人久久大香线蕉综合| 久久精品一区二区影院| 久久综合九色综合欧美狠狠| AAA级久久久精品无码片| 久久精品国产色蜜蜜麻豆| 亚洲人成无码网站久久99热国产 | 久久久久亚洲精品无码网址| 99精品久久精品| 精品九九久久国内精品| 久久久精品国产sm调教网站| 国产亚洲精久久久久久无码77777| 久久天天躁狠狠躁夜夜2020老熟妇| 久久精品国产亚洲一区二区| 嫩草伊人久久精品少妇AV| 无码人妻精品一区二区三区久久久| 久久人与动人物a级毛片|