青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

07年我寫了一篇文章叫《我的網絡模塊設計》,姑且叫那個為第一版吧,由于持續對網絡模塊進行改進,所以現在的實現和當時有很大改變,加上上層應用越來越多,又經過了幾年時間考驗,現在的實現方式比之前的更靈活更有效率,也因為最近看了一些人做網絡程序多年竟毫無建樹,一直要用別人寫的網絡模塊,所以有感而寫此文,為了使得此文不受上一篇《我的網絡模塊設計》的影響,我決定寫之前不看原來的文章,所以此文跟原文那篇文章可能沒有太多相似性。
 一個基本的網絡模塊,無非就是管理N個連接,快速處理每個連接的收發數據、消息等,所謂好的網路模塊,無非就是穩定、高效、靈活,下面分幾部分來寫:
 一、 連接管理
 之所以首先寫連接管理,是因為連接管理是核心,也是最難的地方,我寫第一個網絡庫之前,搜索過很多當時可以找到的例子工程,當時幾乎找不到可穩定運行的工程,當然更找不到好的,于是摸索前進,期間對連接管理使用了各種方法,從最早一個cs(臨界區CriticalSection,我簡稱cs),recv send都用這個cs,到后來send用一個cs,recv用一個cs,用多個的時候還出過錯,最后使用一個cs+一個原子值ref管理一個連接,每個連接send的時候用cs,recv的時候用ref,如果該連接的消息要跨線程異步執行,也使用ref,如此較簡單的解決了連接管理的問題。
 同樣使用生存期管理方法,也有人用智能指針,雖然原理和我直接操縱生存期一樣,但實現方法畢竟不同,不過我為了讓實現依賴少一些沒有引入智能指針。
 當然我后來也發現很多人不是用這種方法,如有些人就id來管理連接,每個連接分個id,其他操作全部用id,每次對連接的調用先翻譯一下,如果id找得到映射目標就調用,否則就說明該連接不存在了,這種方法簡單只是不直接,多了個查找過程,另外查找的時候可能還需要全局鎖(這依賴于連接數據組織)。
 也有人使用一個線程管理連接,其他所有與該連接有關的生存期問題全部到該線程處理,這樣也是可行的,只是需要做一個較好的包裝,如果包裝好上層調用方便,如果包裝不好,可能上層調用就有一些約束。
 雖然各種方法都有人使用,但我一直選擇直接的生存期管理方法,其實內部實現的時候還是有很多優化措施的,減少了大量addref、release的調用,進一步提高了效率。
 二、 線程組
 我最初做網絡庫的時候還不是很清楚上層如何使用這個庫,后來在上面做了幾個應用之后慢慢有了更多想法,最近的網絡庫是設計了這么幾組線程:io線程組、同步線程組、異步線程組、時鐘線程組、log線程組,每組線程都可開可關,就算io線程組也是可關的,這只是為了整個庫更靈活適用性更廣泛,如只用同步線程組或異步線程組僅將這個線程組當一個消息隊列使用。
 Io線程組就是處理io收發的,listen recv send 以及解密解壓縮都是在這組線程,一般這組線程會開2個或2*cpu個。
 同步線程組,一般這組線程開1個,用來處理logic。
 異步線程組,這組線程根據需要開0個或n個,簡單應用無db等慢速操作的應用不開,有很多db等慢速操作的可以開很多個。
 時鐘線程組,一般不開或開1個。
 Log線程組,一般開1個,主要為了避免其他線程調用WriteLog的時候被磁盤io阻塞,所以弄了一個log線程。
 其實還有一個主線程,我的每組線程(包括主線程)都支持事件和定時器,io線程、同步線程、異步線程組、時鐘線程組、甚至log線程組都支持事件和定時器,到去年我還只是讓每組線程都支持事件,今年為了更好的使用時鐘我給每組線程設計了定時器,現在定時器線程組有點雞肋的味道,一般是用不上專門的定時器線程組,不過我還沒有將它刪掉,主要在我的設計里面,它和同步異步線程組一樣,都只是一組線程,如果必要的時候可以將它用作同步線程或者異步線程組,所以繼續保留了它的存在。
 這幾組線程之間都是可互發消息的,所以一個邏輯要異步到別的線程執行是非常方便的,只要調用一下PostXXEvent(TlsInfo *ptls, DWORD dwEvent, WPARAM wParam, LPARAM lParam);我憑借這個設計使得這套網絡庫幾乎可以適用上層各種應用,不管是非常簡單的網絡應用還是復雜的,一框打盡。對最簡單的,一個io線程搞定,其他線程全關,對于復雜的io線程+同步+異步+log全開。
 三、 內存池
 內存池其實沒有想象中的那么神秘,當然如果要讓一個網絡程序持續7*24小時穩定高效運行,內存池幾乎必不可少的,內存池的作用首先是減少內存碎片,其次是為了提高速度,我想這兩點很容易想明白的,關于內存池我之前寫了系列文章,可參考我的博客:
 
《內存池之引言》 http://blog.csdn.net/oldworm/archive/2010/02/04/5288985.aspx
 《單線程內存池》 http://blog.csdn.net/oldworm/archive/2010/02/04/5289003.aspx
 《多線程內存池》 http://blog.csdn.net/oldworm/archive/2010/02/04/5289006.aspx
 《dlmalloc、nedmalloc》 http://blog.csdn.net/oldworm/archive/2010/02/04/5289010.aspx
 《線程關聯內存池》 http://blog.csdn.net/oldworm/archive/2010/02/04/5289015.aspx
 《線程關聯內存池再提速》 http://blog.csdn.net/oldworm/archive/2010/02/04/5289018.aspx
 
四、 定時器
 關于定時器,上面講線程組的時候已經講過,我現在的設計是每個線程(包括主線程)都支持定時器,調用方法都是一樣的,回調函數形式也是一樣的,由于定時器放到各組線程里面,所以減少了線程之間的切換,提高了效率。
 關于定時器,可參考《定時器模塊改造》 http://blog.csdn.net/oldworm/archive/2010/09/11/5877425.aspx
 
五、 包格式
 關于包格式可參考《常用cs程序自定義數據包描述》 http://blog.csdn.net/oldworm/archive/2010/03/24/5413013.aspx
 
六、 Buffer
 之前的文章其實我一直沒有提過我的buffer,其實我的buffer設計是很靈活的,現在它和pool也是有些關聯的,我的poolset其實底下就是按照各種不同大小的buffer預設的尺寸。Buffer我設計為循環式,不允許回繞,包含
 Char *pbase 塊基址
 Char *pread 當前讀指針
 Char *pwrite 當前寫指針
 DWORD tag;
 Buffer *next;
 Capacity 總分配尺寸,上面分配的時候可能只是指定了19,但實際可能分配的是32個字節,所以內部用的時候要根據capacity來最大限度的利用緩沖區。
 Buffer分配還利用了一個技巧,事實上分配的時候是一次分配一個需要的大緩沖,前面為Buffer自身的數據,后面為數據部分,pbase指向數據部分,這樣處理減少了一次分配,我估計很多人都在用這個技巧。
 Pwrite總是不會小于pread的,但pread可能和pbase不一樣,僅當后面空余空間不夠用的時候才可能會移動數據,否則數據不會移動。
 WSARecv的時候我是這么處理的,如果首次獲取了一個包的一部分,但buffer中還有足夠的空間放下包的剩余部分,我不會再分配一個buffer去recv,而是直接用原buffer指定一個合適的偏移和size去WSARecv,這樣可以最大限度的減少復制。
 剛才還有朋友問到我recv的層次組織,我的網絡庫里面是這樣組織的,OnRecv是個虛函數,最基礎的IocpClient的OnRecv只處理數據而不解析格式,IocpClientMsg就會認識默認的一種包格式,這個類的OnRecv會將m_recvbuf中的數據組織為msg,并盡可能的一次返回更多個msg,回調OnMsg函數,由上層決定該消息在哪個線程處理,這樣我認為是最靈活的,如果是個很小的server,可能直接就在io線程里面處理了,也可postevent到同步線程處理,亦可PostEvent到異步線程處理。
 
七、 TLSINFO
 TlsInfo顧名思義就是每個線程關聯的一組數據,暫時我還沒有看到別人這么設計,也許我設計得有些復雜了,在這個數據里面有一些常用的和該線程相關的數據,如該線程的分配基、步長,用這兩個參數可讓每個線程制造出唯一序列,還有常用pool的地址,如tm_pool *p1k; tm_pool *p2k;… 這樣設計使得要分配的時候直接取tm_pool,最大限度的發揮了分配速度,還有一些常規參量long c; long d; DWORD a; DWORD b;… 這幾個值可理解為棧內值,其實為了減少上層調用復雜度的,如我將一個連接的包從io線程PostEvent到同步線程處理,PostEvent首參數就是tlsinfo,PostEvent會根據tlsinfo里面的一個內部值決定是不是要調用addref,因為我有個地方預增了2,所以大多數情況下在io發到其他線程的時候是無需調用addref的,提高了效率,tlsinfo里的其他一些值上層應用可使用,用在邏輯處理等情況下。
 
八、 性能分析
 *nix下有很多知名的網絡庫,但在win下特別是使用iocp的庫里面,一直就沒有一個能作為基準的庫,即使asio也因為出來太晚不為大多數人熟悉而不能成為基準庫,libevent接iocp由于采用0 buffer模擬所以也沒有發揮出足夠的性能,對比spserver我比它快70%左右,我總在想要是微軟能將他那個iocp的例子寫得更好一點就好了,至少學的人有一個更高一點的基礎,而不至于讓http://www.codeproject.com/KB/IP/iocp_server_client.aspx這樣的垃圾代碼都能成為很多人的樣板。
 
九、 雜談
 為了寫好一個win下穩定高效的網絡庫,我07年的時候幾乎搜遍了那個時間段之前所有能找到的iocp例子,還包括通過朋友等途徑看到的如snda等網絡庫,可惜真沒找到好的,大多數例子是只要多線程發起幾千個連接不斷發送數據馬上就死了,偶爾幾個不死的(包括snda的)只要隨機連接并斷開就會產生句柄泄漏,關閉所有連接之后句柄并不關閉等,也就是說這些例子連基本的生存期管理都沒搞定,能通過生存期管理并且不死的只有有限的幾個,可惜性能又太差,杯具啊。
 早年寫網絡庫的時候也加入了sodme在google上建的那個群,當時群還是很熱鬧的,可惜大多數人都是摸索,所以很多問題只是討論卻從無定論,沒有誰能說服別人,也沒有人可輕易被說服,要是現在或許有一些很有經驗的人,可惜那個群由于GFW現在雖能訪問也不大活躍了。
 最近看到有些寫網絡程序7年甚至更久的人還在用libevent、ace等感想很復雜,可悲的是那些人還沒意識到用一個庫和寫一個庫有多大的區別,可能那些人一輩子也認識不到寫一個庫比用一個庫難多少,那些人以為這些庫基本會用了,讓他自己去寫也基本是照這個模式,不會有什么突破,就無需自己動手了,悲哀啊。當然,要寫一個穩定的網絡庫需要耗費很多時間,特別是要寫一個能和知名庫性能接近或更好的庫,更是要費神費力,沒點耐心和持久力是不可能做好的。在中文領域隨便查什么稍有些名氣的代碼,總是能找到很多剖析類文章,可原創的東西總是很少,也不知道那些大俠怎么搞的,什么都能剖析可怎么總寫不出什么像樣的東西呢。
 其實本來沒有打算寫這篇文章,可能是看了陳碩的muduo才使得我有了寫出來的沖動,大概是受到他的開源鼓勵吧。
 謹以此文記錄本人最近3年對網絡模塊的修改并簡短總結。

 

Posted on 2010-10-03 14:25 袁斌 閱讀(3284) 評論(5)  編輯 收藏 引用 所屬分類: win32 、游戲開發

Feedback

# re: 我的網絡模塊設計第二版  回復  更多評論   

2010-10-03 14:54 by true
雜談中的幾句似乎有些言重了,技術以實用為本,應該允許百家爭鳴,很多時候使用libevent,ace是因為他們在網絡庫開發方面,已經或多或少的成為了標準,容易為大家接受,況且在整個系統架構方面,網絡庫本身已經越來越不重要了。

# re: 我的網絡模塊設計第二版  回復  更多評論   

2010-10-03 23:10 by 袁斌
@true
謝謝批評,虛心接受。

# re: 我的網絡模塊設計第二版  回復  更多評論   

2010-10-04 09:28 by cppexplore
頂貼支持!

# re: 我的網絡模塊設計第二版  回復  更多評論   

2010-10-05 20:30 by 飯中淹
不錯,深有同感。
不過自己做庫,也有個很嚴重的問題,要想突破自己,也是比較困難的。
我自己維護了一個類似STL的庫,一個網絡庫,還有很多雜七雜八的東西。很多次重構之后,很多架構依然還存在著,只是不斷的修修補補。有時候想推翻重來,卻總是因為各種原因而放棄或者失敗了。
可能做項目的時候,不適合去做庫的推翻重來。
不過有時候做項目時,偶爾會來一些靈感,突然獲得一個能夠推翻之前庫里的東西的想法,但是卻遲遲無法更新到庫里面。因為心里在害怕,沒有大量測試的代碼,會導致庫的不穩定。

# re: 我的網絡模塊設計第二版  回復  更多評論   

2010-10-10 20:05 by Avlee
@true
未見得,特別是ACE,大部分時候是不錯的,就是有時候(偶爾)會造成系統崩潰,幾乎不留下任何痕跡,很難查找原因。
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美成人性生活| 亚洲精品国产精品国产自| 99热在线精品观看| 亚洲全部视频| 亚洲午夜激情网页| 亚洲午夜精品久久久久久浪潮| 国产精品久久91| 久久九九99| 欧美成人一区二区三区片免费| 一区二区欧美日韩| 亚洲摸下面视频| 在线看国产一区| 日韩午夜高潮| 国产一区在线播放| 91久久国产综合久久91精品网站| 欧美精品粉嫩高潮一区二区| 午夜伦欧美伦电影理论片| 久久国产精品99精品国产| 夜夜嗨av一区二区三区四季av| 亚洲免费小视频| 亚洲九九精品| 亚洲无线一线二线三线区别av| 欧美一区二区三区久久精品 | 亚洲黄色小视频| 亚洲人成网站999久久久综合| 国产精品二区在线| 老司机免费视频一区二区| 欧美理论片在线观看| 久久www成人_看片免费不卡| 欧美韩日一区二区| 久久久久久综合网天天| 欧美午夜精品久久久久久浪潮| 老鸭窝毛片一区二区三区| 欧美日韩综合视频网址| 欧美高清免费| 国产综合在线视频| 亚洲一区二区三区国产| 夜夜嗨av一区二区三区| 另类激情亚洲| 久久综合精品国产一区二区三区| 国产精品v欧美精品v日本精品动漫| 欧美激情bt| 狠狠色狠狠色综合日日tαg | 亚洲电影第1页| 国产精品永久免费视频| 一本久久综合亚洲鲁鲁五月天| 亚洲高清视频一区| 欧美一区在线看| 小嫩嫩精品导航| 欧美午夜一区二区| 亚洲精品之草原avav久久| 亚洲欧洲日产国产网站| 久久久久久穴| 老司机精品视频网站| 国产在线播放一区二区三区| 亚洲一区二区三区四区视频| 中文在线不卡| 欧美视频在线视频| 99这里有精品| 亚洲男同1069视频| 国产精品久久久久久久久久ktv| 99热这里只有精品8| 亚洲小少妇裸体bbw| 欧美视频四区| 亚洲天堂第二页| 午夜精品影院| 国产午夜亚洲精品不卡| 久久国产综合精品| 欧美jizz19hd性欧美| 亚洲啪啪91| 欧美精品在线免费| 一区二区三区视频在线| 亚洲欧美美女| 国产一区深夜福利| 免费国产一区二区| 亚洲精品日韩在线| 亚洲欧美日韩国产综合在线| 国产精品亚洲第一区在线暖暖韩国| 亚洲欧美国产va在线影院| 久久九九国产精品怡红院| 在线播放豆国产99亚洲| 欧美成人午夜| 亚洲一区二区三区精品视频| 久久久久久亚洲精品中文字幕| 在线成人免费视频| 欧美日韩mp4| 午夜一区二区三区不卡视频| 国产欧美91| 最新日韩在线视频| 欧美亚洲免费电影| 在线日韩中文字幕| 欧美日韩一区二区三区在线看| 亚洲专区国产精品| 欧美黄色片免费观看| 亚洲免费一区二区| 亚洲电影免费观看高清完整版在线观看| 欧美激情中文字幕一区二区| 亚洲欧美在线看| 亚洲欧洲综合| 久久久噜噜噜久久| 亚洲一区二区动漫| 在线观看91精品国产麻豆| 欧美视频中文一区二区三区在线观看 | 国产一区二区欧美| 欧美激情一区二区久久久| 亚洲图片你懂的| 美女视频黄 久久| 亚洲午夜在线| 亚洲人成毛片在线播放| 国产美女扒开尿口久久久| 欧美国产91| 久久久久国内| 亚洲欧美日韩国产综合在线 | 久久久久久网站| 亚洲视频在线观看视频| 亚洲国产日日夜夜| 国产日韩欧美a| 欧美日精品一区视频| 免费成人黄色片| 久久九九免费视频| 亚洲永久免费观看| 99视频精品全部免费在线| 欧美激情在线有限公司| 美女精品国产| 久久五月激情| 久久久精品日韩| 欧美影院视频| 性视频1819p久久| 亚洲自拍高清| 亚洲免费网站| 亚洲自拍偷拍一区| 亚洲无线视频| 亚洲综合第一| 先锋影音久久久| 亚洲尤物影院| 亚洲欧美日韩综合国产aⅴ| 中文国产亚洲喷潮| 宅男66日本亚洲欧美视频| 夜夜躁日日躁狠狠久久88av| 91久久久亚洲精品| 亚洲人成高清| 在线亚洲观看| 亚洲免费在线电影| 午夜视频一区| 欧美一区日本一区韩国一区| 欧美一区二区三区免费大片| 欧美一区国产一区| 六月天综合网| 亚洲国产影院| 99精品99| 性做久久久久久久久| 久久激情网站| 久久综合久久久久88| 欧美激情欧美狂野欧美精品| 欧美精品少妇一区二区三区| 欧美日韩免费一区二区三区视频| 欧美日韩在线电影| 国产欧美日韩一区二区三区在线观看 | 久久久久久亚洲精品中文字幕| 久久精品主播| 老司机凹凸av亚洲导航| 欧美高清视频一区二区三区在线观看| 欧美黄色片免费观看| 亚洲精品小视频| 亚洲午夜久久久久久久久电影网| 亚洲综合99| 久久人人超碰| 欧美日韩精品欧美日韩精品 | 韩国在线视频一区| 亚洲精品一区二区三区樱花| 在线中文字幕不卡| 久久久久久夜| 亚洲欧洲日产国产网站| 亚洲一区激情| 免费观看日韩av| 国产精品海角社区在线观看| 狠狠色综合日日| 在线中文字幕一区| 久久综合九色欧美综合狠狠| 亚洲精品视频在线看| 欧美在线视频导航| 欧美日本三级| 韩国在线一区| 亚洲欧美激情视频| 欧美国产精品v| 亚洲免费人成在线视频观看| 你懂的网址国产 欧美| 国产乱码精品一区二区三区五月婷| 亚洲国产精彩中文乱码av在线播放| 亚洲综合大片69999| 亚洲电影在线观看| 久久精品国产99精品国产亚洲性色| 欧美日韩麻豆| 亚洲国产裸拍裸体视频在线观看乱了中文| 亚洲一区二区三区高清不卡| 欧美电影免费| 久久国产精品久久久久久电车| 欧美色欧美亚洲高清在线视频| 亚洲国产日韩欧美| 久久综合久久美利坚合众国|