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

   C++ 技術中心

   :: 首頁 :: 聯系 ::  :: 管理
  160 Posts :: 0 Stories :: 87 Comments :: 0 Trackbacks

公告

鄭重聲明:本BLOG所發表的原創文章,作者保留一切權利。必須經過作者本人同意后方可轉載,并注名作者(天空)和出處(CppBlog.com)。作者Email:coder@luckcoder.com

留言簿(27)

搜索

  •  

最新隨筆

最新評論

評論排行榜

概述

epoll是linux提供一種多路復用的技術,類似各個平臺都支持的select,只是epoll在內核的實現做了更多地優化,可以支持比select更多的文件描述符,當然也支持 socket這種網絡的文件描述符。linux上的大并發的接入服務器,目前的實現方式肯定都通過epoll實現。


epoll和線程

有很多開發人員用epoll的時候,會開多個線程來進行數據通信,比如一個線程專門accept(我個人早些年在FreeBSD用kqueue的時候,由于對內部機制沒有基本了解也這樣搞),一個線程收發,或者接收和發送都用各自獨立的線程。

通常情況下,accept獨立線程是沒必要的,accept對于內核而言,就應用程序從內核的未完成的SYN隊列讀取一點數據而已。具體參見 accept部分:

TCP三次握手過程與對應的Berkeley Socket APIs的介紹

 

收發獨立成兩個線程也沒有必要,因為大部分的應用服務器,通常情況下,啟動一個線程收發數據,最大數據的收發量瓶頸在于網卡,而不是CPU;像網游接入服務器配置一個KM的網卡,很少有游戲會申請1G的帶寬,那一臺機器得有多少數據輸入和輸出。所以我們通信線程為epoll服務器就夠了。


epoll的基本原理

為了讓某些朋友能讀得更連慣,我還是說一下epoll基本原理。

epoll外部表現和select是一樣的。他提供READ, WRITE和ERROR等事件。

大致流程像下面這樣:

1. 應用注冊感興趣的事件到內核;

2. 內核在某種條件下,將事件通知應用程序;

3. 應用程序收到事件后,根據事件類型做對應的邏輯處理。


原理部分我再說一下,不容易理解的地方,包括水平觸發和邊緣觸發,WRITE事件的事件利用(這個可以結合參考文獻1的kqueue的WRITE事件,原理一致的)和修改事件的細節。

水平觸發

READ事件,socket recv buff有數據,將一直向應用程序通知,直到buff為空。

WRITE事件,socket send buff從滿的狀態到可發送數據,將一直通知應用程序,直到buff滿。


邊緣觸發

READ事件,socket recv buff有數據了,只通知應用一次,不管應用程序有沒有調用read api,接下來都不通知了。

WRITE事件,socket send buff從滿的狀態到可以發送數據,只通知一次。

上面這個解釋不知道大家能否理解,也只能這樣說了。有疑問的做一下試驗。另外,這些細節的東西,前幾年固定下來后,這幾年做的項目,是直接用的,也就很少在涉及細節,是憑理解和記憶寫下的文字,萬一有錯請指正^-^。


WRITE事件的利用

這個還一下不好描述。大概描述一下,詳細看參考文獻1。大致這樣:

1. 邏輯層寫數據到應用層的發送buff,向epoll注冊一下WRITE事件;

2. 這時epoll會通知應用程序一個WRITE事件;

3. 在WRITE事件響應函數里,從應用層的發送buff讀數據,然后用socket send api發送。

因為我在很多實際項目中,看到大家沒有利用epoll的WRITE的事件來發數據,特意地說一下。大部分的項目,是直接輪詢應用程序的發送隊列,我早期項目也是這么干的。


epoll的修改事件

對于這個我的映像比較深刻。epoll的修改事件比較坑爹,不能單獨修改某個事件!怎么說呢?比如epoll里已經注冊了READ&WRITE事件,你如果想單單重注冊一下WRITE事件而且READ事件不變,epoll的epoll_ctl API是做不到的,你必須同時注冊READ&WRITE,這個在下面的代碼中可以看到。FreeBSD的kqueue在這一點完全滿足我們程序員的要求。


抽象epoll API

我把herm socket epoll封裝部分貼出來,讓朋友們參考一下epoll的用法。大部分錯誤拋異常代碼被我去掉了。

 

  1. class Multiplexor
  2. {
  3. public:
  4. Multiplexor(int size, int timeout = -1, bool lt = true);
  5. ~Multiplexor();
  6. void Run();
  7. void Register(ISockHandler* eh, MultiplexorMask mask);
  8. void Remove(ISockHandler* eh);
  9. void EnableMask(ISockHandler* eh, MultiplexorMask mask);
  10. void DisableMask(ISockHandler* eh, MultiplexorMask mask);
  11. private:
  12. inline bool OperateHandler(int op, ISockHandler* eh, MultiplexorMask mask)
  13. {
  14. struct epoll_event evt;
  15. evt.data.ptr = eh;
  16. evt.events = mask;
  17. return epoll_ctl(m_epfd, op, eh->GetHandle(), &evt) != -1;
  18. }
  19. private:
  20. int m_epfd;
  21. struct epoll_event* m_evts;
  22. int m_size;
  23. int m_timeout;
  24. __uint32_t m_otherMasks;
  25. };
  1. Multiplexor::Multiplexor(int size, int timeout, bool lt)
  2. {
  3. m_epfd = epoll_create(size);
  4. if (m_epfd == -1)
  5. throw HERM_SOCKET_EXCEPTION(ST_OTHER);
  6. m_size = size;
  7. m_evts = new struct epoll_event[size];
  8. m_timeout = timeout;
  9. // sys/epoll.h is no EPOLLRDHUP(0X2000), don't add EPOLLRDHUP
  10. m_otherMasks = EPOLLERR | EPOLLHUP;
  11. if (!lt)
  12. m_otherMasks |= EPOLLET;
  13. }
  14. Multiplexor::~Multiplexor()
  15. {
  16. close(m_epfd);
  17. delete[] m_evts;
  18. }
  19. void Multiplexor::Run()
  20. {
  21. int fds = epoll_wait(m_epfd, m_evts, m_size, m_timeout);
  22. if (fds == -1)
  23. {
  24. if (errno == EINTR)
  25. return;
  26. }
  27. for (int i = 0; i < fds; ++i)
  28. {
  29. __uint32_t evts = m_evts[i].events;
  30. ISockHandler* eh = reinterpret_cast<ISockHandler*>(m_evts[i].data.ptr);
  31. int stateType = ST_SUCCESS;
  32. if (evts & EPOLLIN)
  33. stateType = eh->OnReceive();
  34. if (evts & EPOLLOUT)
  35. stateType = eh->OnSend();
  36. if (evts & EPOLLERR || evts & EPOLLHUP)
  37. stateType = ST_EXCEPT_FAILED;
  38. if (stateType != ST_SUCCESS)
  39. eh->OnError(stateType, errno);
  40. }
  41. }
  42. void Multiplexor::Register(ISockHandler* eh, MultiplexorMask mask)
  43. {
  44. MultiplexorMask masks = mask | m_otherMasks;
  45. OperateHandler(EPOLL_CTL_ADD, eh, masks);
  46. }
  47. void Multiplexor::Remove(ISockHandler* eh)
  48. {
  49. // Delete fd from epoll, don't need masks
  50. OperateHandler(EPOLL_CTL_DEL, eh, ALL_EVENTS_MASK);
  51. }
  52. void Multiplexor::EnableMask(ISockHandler* eh, MultiplexorMask mask)
  53. {
  54. MultiplexorMask masks = mask | Herm::READ_MASK | Herm::WRITE_MASK;
  55. OperateHandler(EPOLL_CTL_MOD, eh, masks | m_otherMasks);
  56. }
  57. void Multiplexor::DisableMask(ISockHandler* eh, MultiplexorMask mask)
  58. {
  59. MultiplexorMask masks = (Herm::READ_MASK | Herm::WRITE_MASK) & (~mask);
  60. if (!OperateHandler(EPOLL_CTL_MOD, eh, masks | m_otherMasks))
  61. throw HERM_SOCKET_EXCEPTION(ST_OTHER);
  62. }

上面類就用到epoll_create(), epoll_ctl()和epoll_wait(),以及幾種事件。epoll用起來比select清爽一些。


大致用法類似下面這樣:

先定義一個Handler

 

  1. class StreamHandler : public Herm::ISockHandler
  2. {
  3. public:
  4. virtual Herm::Handle GetHandle() const;
  5. virtual int OnReceive(int);
  6. virtual int OnSend(int);
  7. };

 

在OnReceive()處理收到數據的動作,在OnSend()。。。。

在通信線程中,大概類似這樣的代碼,實際看情況。

 

  1. Multiplexor multiplexor;
  2. StreamHandler sh;
  3. multiplexor.Register(&sh, READ_EVT);
  4. multiplexor.Run(...);


 

參考文獻

1.

 

使用 kqueue 在 FreeBSD 上開發高性能應用服務器

FreeBSD上kqueue和epoll是類似的,有興趣的朋友請參考。

http://blog.csdn.net/herm_lib/article/details/6047038

 

2.

【Herm程序員開發指導】第2章 Herm Framework和網絡通信組件

這里涉及到epoll的通信層如何和邏輯數據交互的問題

 

http://blog.csdn.net/herm_lib/article/details/5980657

posted on 2013-09-17 17:31 C++技術中心 閱讀(3325) 評論(0)  編輯 收藏 引用 所屬分類: Linux 編程
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲第一区在线观看| 久久视频免费观看| 一本久久综合| 欧美日韩精品在线视频| 欧美日韩国产综合一区二区| 久久国产精品网站| 欧美国内亚洲| 麻豆精品视频| 美女精品国产| 欧美激情国产精品| 久久天天躁狠狠躁夜夜av| 亚洲第一区在线| 亚洲人人精品| 午夜激情综合网| 久久国产精品黑丝| 好看的亚洲午夜视频在线| 尤物精品国产第一福利三区| 亚洲精品社区| 亚洲国产精品va在线看黑人 | 午夜在线视频一区二区区别| 久久久www成人免费精品| 久久只有精品| 亚洲一区影院| 欧美午夜电影在线| 91久久精品www人人做人人爽| 亚洲欧美自拍偷拍| 欧美激情中文字幕乱码免费| 葵司免费一区二区三区四区五区| 欧美体内she精视频| 一区二区在线观看视频| 亚洲一区二区三区国产| 欧美一区二区三区在线| 欧美 日韩 国产一区二区在线视频| 欧美激情视频一区二区三区免费| 亚洲国产精品成人一区二区| 亚洲精品护士| 久久精品视频99| 亚洲免费观看在线观看| 香蕉精品999视频一区二区 | 99在线精品视频| 欧美福利一区二区| 亚洲欧美在线另类| 国产精品va在线| 亚洲性人人天天夜夜摸| 亚洲大片精品永久免费| 久久免费视频网站| 国产婷婷色一区二区三区四区| 亚洲国产精品一区二区第四页av | 午夜日韩av| 欧美高清视频免费观看| 久久天天躁狠狠躁夜夜av| 1000部精品久久久久久久久| 久久天堂成人| 欧美成人久久| 亚洲尤物视频网| 久久精品青青大伊人av| 国产午夜一区二区三区| 久久全球大尺度高清视频| 亚洲视频在线观看免费| 欧美日韩美女在线观看| 日韩特黄影片| 亚洲高清不卡在线| 久久精品72免费观看| 国产美女扒开尿口久久久| 亚洲一区二区成人在线观看| 国产日韩欧美一区| 一二三区精品福利视频| 亚洲国内高清视频| 久久久久久久久久久一区 | 一本不卡影院| 一本一本久久a久久精品综合麻豆| 亚洲欧美精品在线观看| 久久天天躁狠狠躁夜夜爽蜜月| 久久精品麻豆| 黑人巨大精品欧美黑白配亚洲 | 欧美精品电影在线| 亚洲欧美日韩精品综合在线观看 | 欧美啪啪成人vr| 免费成人黄色| 国内伊人久久久久久网站视频| 一本一本久久| 小黄鸭精品aⅴ导航网站入口| 女生裸体视频一区二区三区| 久久精品国产99国产精品澳门| 久久爱另类一区二区小说| 中文在线一区| 亚洲亚洲精品在线观看 | 99xxxx成人网| 亚洲免费激情| 欧美天堂亚洲电影院在线观看 | 国产一区av在线| 亚洲日本乱码在线观看| 国产欧美日本| 欧美xxx在线观看| 亚洲激情六月丁香| 亚洲一区精品视频| 欧美日韩在线播放一区二区| 久久婷婷国产综合国色天香| 欧美三级日韩三级国产三级| 夜夜嗨av一区二区三区四季av| 另类成人小视频在线| av成人免费观看| 国产视频观看一区| 久久精品91久久香蕉加勒比| 久久国产精品电影| 国产日韩欧美一二三区| 性一交一乱一区二区洋洋av| 99re6这里只有精品| 久久久国产亚洲精品| 亚洲精品一区二区三区福利| 欧美freesex8一10精品| 最近中文字幕mv在线一区二区三区四区| 亚洲精品久久久久久久久| 国产一区91| 欧美精品一区二区三区一线天视频 | 免费毛片一区二区三区久久久| 久久久久国产一区二区三区| 亚洲人成在线免费观看| 国模私拍一区二区三区| 欧美日韩免费在线观看| 欧美在线免费观看亚洲| 亚洲欧洲一区二区天堂久久 | 国产精品久久久一区二区| 日韩午夜在线电影| 亚洲一区二区三| 亚洲资源av| 亚洲一区在线直播| 99国内精品| 国产一区二区高清视频| 欧美午夜精品理论片a级按摩 | 亚洲高清资源| 欧美三级网址| 亚洲午夜激情| 亚洲淫性视频| 亚洲欧美一级二级三级| 久久精品导航| 欧美韩国日本综合| 国产精品毛片大码女人| 国产一区二区三区日韩欧美| 国外精品视频| 99在线|亚洲一区二区| 亚洲一区免费看| 欧美成人午夜77777| 亚洲神马久久| 老色鬼精品视频在线观看播放| 欧美精品黄色| 黄色小说综合网站| 亚洲欧美激情一区二区| 欧美成人精品在线播放| av成人手机在线| 你懂的网址国产 欧美| 国产精品网站一区| 99re热这里只有精品免费视频| 欧美在线视频二区| 夜夜狂射影院欧美极品| 久久综合综合久久综合| 欧美专区在线观看一区| 欧美日韩免费看| 91久久精品国产91性色| 久久精品人人做人人爽电影蜜月| 欧美激情精品久久久| 国产日韩亚洲欧美精品| 亚洲欧美日韩精品久久奇米色影视| 欧美影院成人| 欧美一级淫片aaaaaaa视频| 欧美日韩一区二区在线观看| 亚洲国产成人不卡| 蜜臀a∨国产成人精品| 欧美专区18| 久久www免费人成看片高清| 久久九九电影| 欧美一区二区免费| 午夜精品久久久久久99热| 欧美国产日韩视频| 蜜臀va亚洲va欧美va天堂| 国产精品一区二区三区乱码| 久久久久久久一区二区三区| 欧美日韩一区在线播放| 亚洲第一页在线| 在线欧美福利| 欧美精品久久久久久久免费观看| 毛片一区二区| 91久久黄色| 欧美日韩中文在线| 亚洲欧美99| 欧美成人精品| 欧美日韩中文字幕精品| 欧美国产日韩免费| 久久久国产精彩视频美女艺术照福利 | 香蕉久久夜色精品国产| 欧美一级网站| 亚洲一级网站| 欧美88av| 猛干欧美女孩| 有坂深雪在线一区| 亚洲欧美日韩精品久久奇米色影视 | 日韩视频二区| 狼人社综合社区| 欧美日韩hd| 9国产精品视频|