{"id":66701,"date":"2026-01-27T11:25:12","date_gmt":"2026-01-27T03:25:12","guid":{"rendered":"https:\/\/www.wsisp.com\/helps\/66701.html"},"modified":"2026-01-27T11:25:12","modified_gmt":"2026-01-27T03:25:12","slug":"%e3%80%90c-linux%e5%ae%9e%e6%88%98%e9%a1%b9%e7%9b%ae%e3%80%91%e4%bb%bfmuduo%e5%ba%93%e5%ae%9e%e7%8e%b0%e9%ab%98%e6%80%a7%e8%83%bdreactor%e6%a8%a1%e5%bc%8ftcp%e6%9c%8d%e5%8a%a1%e5%99%a8%ef%bc%88","status":"publish","type":"post","link":"https:\/\/www.wsisp.com\/helps\/66701.html","title":{"rendered":"\u3010C++\/Linux\u5b9e\u6218\u9879\u76ee\u3011\u4effmuduo\u5e93\u5b9e\u73b0\u9ad8\u6027\u80fdReactor\u6a21\u5f0fTCP\u670d\u52a1\u5668\uff08\u6df1\u5ea6\u89e3\u6790\uff09"},"content":{"rendered":"<p>\u524d\u8a00&#xff1a;<\/p>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u672c\u6587\u5b9e\u73b0\u7684\u662f\u4e00\u4e2a\u4effmuduo\u5e93\u6838\u5fc3\u8bbe\u8ba1\u7684\u9ad8\u6027\u80fdTCP\u670d\u52a1\u5668&#xff0c;\u57fa\u4e8e\u591aReactor\u6a21\u5f0f&#043;epoll&#043;\u591a\u7ebf\u7a0b&#043;\u65f6\u95f4\u8f6e\u5b9a\u65f6\u5668&#xff0c;\u8986\u76d6Linux\/C&#043;&#043;\u7f51\u7edc\u7f16\u7a0b\u6838\u5fc3\u77e5\u8bc6\u70b9\u3002<\/p>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u4f5c\u4e3a\u5b66\u4e60\u5b8cC&#043;&#043;\/Linux\u540e\u7684\u5b9e\u6218\u9879\u76ee&#xff0c;\u68b3\u7406\u5e95\u5c42\u7f51\u7edc\u6846\u67b6\u7684\u8bbe\u8ba1\u601d\u8def&#xff0c;\u4e5f\u4e3a\u5b9e\u4e60\u6c42\u804c\u592f\u5b9e\u5e95\u5c42\u7f16\u7a0b\u80fd\u529b\u3002<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u8bfb\u5b8c\u672c\u6587\u5e0c\u671b\u80fd\u5e2e\u4f60\u7406\u89e3\u591aReactor\u6a21\u5f0f\u7684\u843d\u5730\u5b9e\u73b0\u3001muduo\u6838\u5fc3\u6a21\u5757\u7684\u8bbe\u8ba1\u903b\u8f91&#xff0c;\u4ee5\u53caLinux\u7f51\u7edc\u7f16\u7a0b\u7684\u5173\u952e\u5751\u70b9\u3002\u9879\u76ee\u6e90\u7801gitee\u8fde\u63a5&#xff1a;\u9879\u76ee\u6e90\u7801\u8fde\u63a5<\/p>\n<h2>\u4e00&#xff1a;\u9879\u76ee\u80cc\u666f<\/h2>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 muduo\u5e93\u662f\u9648\u7855\u8001\u5e08\u7684\u5f00\u6e90\u9ad8\u6027\u80fd\u7f51\u7edc\u5e93&#xff0c;\u6838\u5fc3\u662f&#xff1a;Reactor &#043; \u591a\u7ebf\u7a0b &#043; \u4e8b\u4ef6\u9a71\u52a8&#xff0c;\u8f7b\u91cf\u3001\u9ad8\u6548\u3001\u6613\u6269\u5c55\u3002\u672c\u9879\u76ee\u5e76\u975e\u76f4\u63a5\u7167\u642cmuduo\u7684\u5f00\u6e90\u5e93&#xff0c;\u800c\u662f\u63d0\u53d6\u6838\u5fc3\u8bbe\u8ba1&#xff0c;\u5982&#xff1a;EventLoop\u3001Channel\u3001Connection\u5206\u5c42&#xff0c;\u5b9e\u73b0\u8f7b\u91cf\u7ea7\u7248\u672c&#xff0c;\u805a\u7126\u6838\u5fc3\u539f\u7406\u3002<\/p>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u6280\u672f\u6d89\u53ca&#xff1a;C&#043;&#043;\u9762\u5411\u5bf9\u8c61\u3001\u6a21\u7248\u3001\u591a\u6001\u3001Linux IO \u591a\u8def\u590d\u7528\u3001\u591a\u7ebf\u7a0b\u540c\u6b65\u3001\u8bbe\u8ba1\u6a21\u5f0f\u3001\u7c7b\u578b\u64e6\u9664\u3001\u6761\u4ef6\u53d8\u91cf\u3001\u4e92\u65a5\u9501\u3001\u667a\u80fd\u6307\u9488\u7b49\u3002<\/p>\n<h2>\u4e8c&#xff1a;\u6838\u5fc3\u8bbe\u8ba1\u601d\u60f3<\/h2>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u6838\u5fc3\u8bbe\u8ba1\u91c7\u7528\u4e3b\u4eceReactor&#043;\u591a\u7ebf\u7a0b\u6a21\u5f0f\u2014\u2014\u4e3bReactor\u6765\u76d1\u63a7\u670d\u52a1\u5668\u7684listen_fd&#xff0c;\u4ece\u5c5eReactor\u7528\u4e8e\u76d1\u542c\u6bcf\u4e00\u4e2a\u5ba2\u6237\u7aef\u8fde\u63a5\u7684\u4e8b\u4ef6&#xff0c;\u6bcf\u4e00\u4e2aEventLoop\u4e00\u4e2aReactor&#xff0c;\u4e00\u4e2a\u7ebf\u7a0b\u7ba1\u7406\u591a\u4e2a\u8fde\u63a5(\u591a\u4e2aReactor)&#xff0c;\u7ebf\u7a0b\u6c60\u91c7\u53d6RR\u8f6e\u8be2\u7684\u65b9\u5f0f\u3002<\/p>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u4ec0\u4e48\u662fReactor&#xff0c;\u4e3e\u4f8b\u5c31\u662fReactor\u50cf\u662f\u9910\u5385\u91cc\u7684\u670d\u52a1\u5458\u2014\u2014\u670d\u52a1\u5458(EventLoop)\u76ef\u7740\u6240\u6709\u9910\u684c&#xff08;fd&#xff09;&#xff0c;\u54ea\u4e2a\u9910\u684c\u6709\u9700\u6c42(IO\u4e8b\u4ef6)&#xff0c;\u5c31\u558a\u5bf9\u5e94\u7684\u521d\u8bd5(Channel)\u5904\u7406&#xff0c;\u81ea\u5df1\u7ee7\u7eed\u76ef\u7740\u5176\u4ed6\u7684\u9910\u684c\u3002\u5177\u4f53\u6267\u884c\u6d41\u7a0b\u5c31\u662fEventLoop\u7c7b\u542f\u52a8\u540e-&gt;\u5faa\u73af\u6267\u884cepoll_wait-&gt;\u62ff\u5230\u5904\u7406\u5c31\u7eea\u4e8b\u4ef6-&gt;\u6267\u884c\u4efb\u52a1\u961f\u5217\u4e2d\u7684\u4eba\u7269&#xff0c;\u8fd9\u5c31\u662fReactor\u7684\u6838\u5fc3\u5faa\u73af\u90e8\u5206\u3002<\/p>\n<h2>\u4e09&#xff1a;\u9879\u76ee\u6574\u4f53\u6784\u67b6\u4e0e\u6a21\u5757\u5212\u5206<\/h2>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u9879\u76ee\u9075\u5faa\u9ad8\u5185\u805a&#xff0c;\u4f4e\u8026\u5408\u7684\u539f\u5219&#xff0c;\u5c06\u6574\u4f53\u67b6\u6784\u62c6\u89e3\u4e3a\u300c\u57fa\u7840\u5de5\u5177\u5c42\u3001\u7f51\u7edc\u57fa\u7840\u5c42\u3001\u4e8b\u4ef6\u9a71\u52a8\u6838\u5fc3\u5c42\u3001\u9ad8\u7ea7\u7279\u6027\u5c42\u3001\u4e1a\u52a1\u6838\u5fc3\u5c42\u300d\u4e94\u5927\u5c42\u7ea7&#xff0c;\u5404\u5c42\u7ea7\u81ea\u4e0a\u800c\u4e0b\u4f9d\u8d56\u3001\u81ea\u4e0b\u800c\u4e0a\u652f\u6491&#xff0c;\u5f62\u6210\u5b8c\u6574\u7684TCP\u670d\u52a1\u5668\u95ed\u73af\u3002\u5177\u4f53\u56fe\u793a\u5982\u4e0b&#xff1a;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"2142\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/01\/20260127032509-697830154d07b.jpg\" width=\"3787\" \/><\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u9879\u76ee\u9664\u5b8f\u65e5\u5fd7\u4e4b\u5916\u603b\u5171\u5206\u4e3a13\u4e2a\u7c7b\u5206\u522b\u662f&#xff1a;<\/p>\n<table border=\"1\" cellpadding=\"1\" cellspacing=\"1\" style=\"width:500px\">\n<tbody>\n<tr>\n<td>\u00a0 \u00a0 \u00a0 \u00a0\u7c7b<\/td>\n<td>\u529f\u80fd\u4ecb\u7ecd<\/td>\n<\/tr>\n<tr>\n<td>Any<\/td>\n<td>\u7c7b\u578b\u64e6\u9664\u7c7b<\/td>\n<\/tr>\n<tr>\n<td>Buffer<\/td>\n<td>\u7528\u6237\u5c42\u7f13\u51b2\u533a\u7c7b<\/td>\n<\/tr>\n<tr>\n<td>Socket<\/td>\n<td>\u7f51\u7edc\u63a5\u53e3\u7c7b&#xff08;\u5c31\u662f\u5c01\u88c5\u7684\u539f\u751fsocket&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>Channel<\/td>\n<td>\u5ba2\u6237\u7aef\u8fde\u63a5\u7684\u7ba1\u7406\u4e8b\u4ef6\u76d1\u63a7\u7c7b<\/td>\n<\/tr>\n<tr>\n<td>Poller<\/td>\n<td>\u7ba1\u7406\u6240\u6709\u5ba2\u6237\u7aef\u8fde\u63a5\u7684Channel<\/td>\n<\/tr>\n<tr>\n<td>EventLoop<\/td>\n<td>Reactor\u7684\u6838\u5fc3\u7c7b&#xff08;\u4e8b\u4ef6\u5904\u7406&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>LoopThread<\/td>\n<td>\u5c01\u88c5EventLoop&#xff0c;\u4e00\u4e2a\u7ebf\u7a0b\u7ba1\u7406\u4e00\u4e2aEventLoop<\/td>\n<\/tr>\n<tr>\n<td>LoopThreadPoll<\/td>\n<td>\u7ebf\u7a0b\u6c60\u7c7b<\/td>\n<\/tr>\n<tr>\n<td>TimerTask<\/td>\n<td>\u5b9a\u65f6\u4efb\u52a1\u7c7b<\/td>\n<\/tr>\n<tr>\n<td>TimerWheel<\/td>\n<td>\u65f6\u95f4\u8f6e(\u6a21\u62df\u79d2\u9488\u8df3\u52a8&#xff0c;\u53bb\u6267\u884c\u5b9a\u65f6\u4efb\u52a1\u7c7b)<\/td>\n<\/tr>\n<tr>\n<td>Connection<\/td>\n<td>\u5ba2\u6237\u7aef(\u5ba2\u6237\u7aeffd)\u8fde\u63a5\u7c7b<\/td>\n<\/tr>\n<tr>\n<td>Acceptor<\/td>\n<td>\u76d1\u542c\u5957\u63a5\u5b57(listen_fd)\u7ba1\u7406\u7c7b<\/td>\n<\/tr>\n<tr>\n<td>TcpServer<\/td>\n<td>\u96c6\u6210\u4e4b\u524d\u7684\u6240\u6709\u7c7b&#xff0c;\u771f\u6b63\u7684\u670d\u52a1\u5668\u7c7b<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u53c8\u5206\u4e3a\u4e94\u4e2a\u5927\u6a21\u5757&#xff1a;\u57fa\u7840\u5de5\u5177\u6a21\u5757\u3001\u7f51\u7edc\u57fa\u7840\u6a21\u5757\u3001\u4e8b\u4ef6\u9a71\u52a8\u6838\u5fc3\u3001\u9ad8\u7ea7\u7279\u6027\u6a21\u5757\u3001\u4e1a\u52a1\u6838\u5fc3\u6a21\u5757\u3002<\/p>\n<h2>\u56db&#xff1a;\u6a21\u5757\u8be6\u7ec6\u4ecb\u7ecd\u6bcf\u4e2a\u6a21\u5757\u4ee5\u53ca\u6bcf\u4e2a\u6a21\u5757\u4e4b\u95f4\u7684\u5173\u8054\u548c\u4f9d\u8d56\u5173\u7cfb<\/h2>\n<h3>4.1\u57fa\u7840\u5de5\u5177\u6a21\u5757<\/h3>\n<h4>4.1.1 \u65e5\u5fd7\u5b8f\u2014\u2014LOG<\/h4>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u65e5\u5fd7\u5b8f\u7684\u8bbe\u8ba1\u521d\u8877\u2014\u2014\u5728\u6d4b\u8bd5\u9879\u76ee\u65f6\u4e3a\u4e86\u65b9\u4fbf\u6211\u4eec\u51c6\u786e\u5feb\u901f\u5730\u627e\u5230\u9519\u8bef\u4fe1\u606f&#xff0c;\u6211\u4eec\u4e00\u822c\u4f1a\u4f7f\u7528\u65e5\u5fd7\u5e2e\u6211\u4eec\u5feb\u901f\u5b9a\u4f4d&#xff0c;\u5728\u65e5\u5fd7\u4e2d\u4e0d\u662f\u5355\u7eaf\u7684\u9519\u8bef\u4fe1\u606f&#xff0c;\u6211\u4eec\u8fd8\u4f1a\u989d\u5916\u7684\u6dfb\u52a0\u9519\u8bef\u6587\u4ef6\u540d&#xff0c;\u884c\u53f7&#xff0c;\u9519\u8bef\u65f6\u95f4\u7b49\u7b49&#xff0c;\u6765\u5e2e\u52a9\u6211\u4eec\u627e\u51fa\u9519\u8bef\u3002\u5177\u4f53\u5982\u4e0b&#xff1a;<\/p>\n<p>#define INF 0<br \/>\n#define DBG 1<br \/>\n#define ERR 2<br \/>\n#define LOG_LEVEL DBG<\/p>\n<p>\/\/\u4f7f\u7528strrchr\u53bb\u627e\u5230\u5206\u5272\u7b26\u4e4b\u540e\u7684\u5b57\u7b26\u4e32<br \/>\n#define SHORT_FILE (strrchr(__FILE__, &#039;\/&#039;) ? strrchr(__FILE__, &#039;\/&#039;) &#043; 1 : __FILE__)<br \/>\n#define LOG(level,fromat,&#8230;) do{\\\\<br \/>\n    if(level&lt;LOG_LEVEL)break;\\\\<br \/>\n    time_t t &#061; time(nullptr);\\\\<br \/>\n    struct tm * ltm &#061; localtime(&amp;t);\\\\<br \/>\n    char time_buf[32]&#061;{0};\\\\<br \/>\n    strftime(time_buf,31,&#034;%H:%M:%S&#034;,ltm);\\\\<br \/>\n    fprintf(stdout , &#034;[thread id:%p time:%s %s:%d]&#034; fromat &#034;\\\\n&#034; ,(void*)pthread_self(),time_buf , SHORT_FILE , __LINE__ , ##__VA_ARGS__);\\\\<br \/>\n}while(0)<\/p>\n<p>#define INF_LOG(fromat , &#8230;) LOG(INF , fromat , ##__VA_ARGS__)<br \/>\n#define DBG_LOG(fromat , &#8230;) LOG(DBG , fromat , ##__VA_ARGS__)<br \/>\n#define ERR_LOG(fromat , &#8230;) LOG(ERR , fromat , ##__VA_ARGS__) <\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u5176\u4e2d\u65e5\u5fd7\u5b8f\u7684\u6d89\u53ca\u5230\u4e86\u53ef\u53d8\u957f\u53c2\u6570&#xff0c;\u4ee5\u53caGNU\u6269\u5c55\u53d8\u957f\u53c2\u6570\u7684\u4f7f\u7528##__VA_ARGS__&#xff0c;\u5f53\u53d8\u957f\u5e38\u6570\u4e3a\u7a7a\u65f6&#xff0c;\u81ea\u52a8\u5220\u9664\u53c2\u6570\u4e2d\u524d\u9762\u7684\u9017\u53f7\u3002\u5176\u6b21\u662f\u6211\u4f7f\u7528\u4e86\u4e00\u4e2a\u5b8f\u51fd\u6570SHORT_FILE\u53bb\u622a\u53d6\u8def\u5f84\u4e2d\u6240\u5bf9\u5e94\u8fd9\u4e2a\u6587\u4ef6\u7684\u6587\u4ef6\u540d&#xff0c;\u5176\u4e2dstrrchr\u2014\u2014\u4ece\u8def\u5f84\u672b\u5c3e\u5f00\u59cb\u627e\u8def\u5f84\u5206\u9694\u7b26&#xff0c;\u4e09\u76ee\u8868\u8fbe\u5f0f\u7684\u76ee\u7684\u662f&#xff0c;\u5982\u679c__FILE__\u5c31\u662f\u6587\u4ef6\u540d\u90a3\u4e48\u5c31\u76f4\u63a5\u8fd4\u56de\u8fd9\u4e2a\u8def\u5f84&#xff0c;\u5982\u679c\u8def\u5f84\u540d\u4e2d\u6709\/\u90a3\u4e48\u5c31\u627e\u5230\u6700\u540e\u4e00\u4e2a\/\u5206\u9694\u7b26\u7684\u4f4d\u7f6e&#043;1\u5c31\u662f\u6587\u4ef6\u540d\u3002\u5177\u4f53\u53ef\u4ee5\u770b\u4ee3\u7801&#xff0c;\u601d\u60f3\u662f\u6bd4\u8f83\u7b80\u5355\u7684\u3002<\/p>\n<h4>4.1.2 Any\u7c7b\u2014\u2014\u7c7b\u578b\u64e6\u9664<\/h4>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u76ee\u7684\u662f\u4e3a\u4e86\u8ba9\u6211\u7684muduo\u670d\u52a1\u5668\u53ef\u4ee5\u652f\u6301\u9002\u914d\u4e0d\u540c\u7684\u534f\u8bae(HTTP\/HTTPS\/FTP)\u7684\u670d\u52a1\u5668&#xff0c;\u8bbe\u8ba1\u4e86\u8fd9\u4e2a\u7c7b\u3002\u4e3b\u8981\u7528\u5230\u4e86\u591a\u6001&#xff0c;\u6a21\u7248\u7c7b\u3002\u4ee3\u7801\u5982\u4e0b&#xff1a;<\/p>\n<p>\/\/\u7c7b\u578b\u64e6\u9664\u5bb9\u5668\u2014\u2014\u5b58\u50a8\u4efb\u610f\u7c7b\u578b\u7684\u4e0a\u4e0b\u6587<br \/>\n\/\/\u7528\u540c\u4e00\u4e2a Any \u5bf9\u8c61\u5c31\u80fd\u5b58\u50a8\u4efb\u610f\u7c7b\u578b\u7684\u6570\u636e&#xff0c;\u800c\u4e0d\u662f\u4e3a int\u3001string\u3001\u81ea\u5b9a\u4e49\u7c7b\u5206\u522b\u521b\u5efa Any&lt;int&gt;\u3001Any&lt;string&gt; \u8fd9\u7c7b\u7ed1\u5b9a\u4e86\u5177\u4f53\u7c7b\u578b\u7684\u5bf9\u8c61\u2014\u2014\u7528\u5728\u5047\u8bbe\u6211\u8981\u7528\u5176\u4ed6\u5e94\u7528\u5c42\u534f\u8bae\u8fd9\u4e2a\u9879\u76ee\u540e\u9762\u5199\u4e86\u4e00\u4e2ahttp\u670d\u52a1\u5668\u6240\u6709\u53ef\u4ee5\u76f4\u63a5\u7528&#xff0c;\u6211\u6362\u4e2ahttps\u4e5f\u53ef\u4ee5\u7528\u2014\u2014\u8fd9\u5c31\u662fAny\u7c7b\u7684\u610f\u4e49\u6240\u5728<br \/>\nclass Any{<br \/>\n    private:<br \/>\n        class holder{<br \/>\n            public:<br \/>\n                virtual ~holder(){}<br \/>\n                virtual const std::type_info&amp; type()&#061;0;<br \/>\n                virtual holder* clone()&#061;0;<br \/>\n        };<br \/>\n        template&lt;class T&gt;<br \/>\n        class placeholder: public holder{<br \/>\n            public:<br \/>\n                placeholder(const T&amp; val):_val(val){}<br \/>\n                virtual const std::type_info&amp; type(){return typeid(T);}<br \/>\n                virtual holder* clone(){return new placeholder&lt;T&gt;(_val);}<br \/>\n                T _val;<br \/>\n        };<br \/>\n        holder* _content;<br \/>\n    public:<br \/>\n        Any():_content(nullptr){}<\/p>\n<p>        template&lt;class T&gt;<br \/>\n        Any(const T&amp; val){<br \/>\n            _content&#061;new placeholder&lt;T&gt; (val);<br \/>\n        }<br \/>\n        Any(const Any&amp; val){<br \/>\n            _content&#061;val._content?val._content-&gt;clone():nullptr;<br \/>\n        }<br \/>\n        ~Any(){delete _content;}<\/p>\n<p>        \/\/\u8fd9\u91ccother\u80fd\u533a\u8bbf\u95ee_content\u79c1\u6709\u6210\u5458\u53d8\u91cf\u662f\u56e0\u4e3a\u662f\u5728swap\u6210\u5458\u51fd\u6570\u4e2d\u3002\u53ea\u6709\u4e0d\u5728Any\u7c7b\u4e2d\u624d\u4e0d\u80fd\u53bb\u8bbf\u95ee\u79c1\u6709\u6210\u5458\u53d8\u91cf\u3002<br \/>\n        Any&amp; swap(Any&amp;other){<br \/>\n            \/\/swap\u51fd\u6570\u8981\u6c42\u4ea4\u6362\u4e24\u4e2a\u53ef\u4fee\u6539\u7684\u5de6\u503c<br \/>\n            std::swap(other._content,_content);<br \/>\n            return *this;<br \/>\n        }<br \/>\n        \/\/\u8fd4\u56de\u5b50\u7c7b\u5bf9\u8c61\u4fdd\u5b58\u7684\u6570\u636e\u7684\u6307\u9488<br \/>\n        template&lt;class T&gt;<br \/>\n        T* get(){<br \/>\n            assert(_content !&#061; nullptr &amp;&amp; &#034;Any object is empty&#034;);<br \/>\n            assert(_content-&gt;type() &#061;&#061; typeid(T) &amp;&amp; &#034;Type mismatch&#034;);<br \/>\n            \/\/\u8fd9\u91cc\u6362\u6210static_cast\u66f4\u597d&#xff0c;static_cast\u662f\u7f16\u8bd1\u65f6\u68c0\u67e5&#xff0c;\u8fd0\u884c\u96f6\u5f00\u9500&#xff0c;\u800c\u4e14\u6211\u5df2\u7ecf\u7528assert\u65ad\u8a00\u4e86\u4e0d\u4f1a\u51fa\u73b0\u7c7b\u578b\u4e0d\u5339\u914d<br \/>\n            \/\/ return &amp;((dynamic_cast&lt;placeholder&lt;T&gt;*&gt;(_content))-&gt;_val);<br \/>\n            return &amp;((static_cast&lt;placeholder&lt;T&gt;*&gt;(_content))-&gt;_val);<br \/>\n        }<\/p>\n<p>        \/\/\u91cd\u8f7d\u8d4b\u503c\u51fd\u6570<br \/>\n        template&lt;class T&gt;<br \/>\n        Any&amp; operator&#061;(const T&amp; val){<br \/>\n            \/\/\u8fd9\u4e00\u6b65\u5f88\u5de7\u5999&#xff0c;\u7701\u53bb\u4e86\u81ea\u5df1\u5199new\u7684\u8fc7\u7a0b\u76f8\u5f53\u4e8e\u4e00\u79cd\u70ab\u6280\u4e86&#xff0c;\u6784\u9020Any\u4e34\u65f6\u5bf9\u8c61&#xff0c;\u7136\u540e\u8c03\u7528swap\u51fd\u6570\u5c06\u4e34\u65f6\u5bf9\u8c61\u4e2d\u7684\u6307\u9488\u548cthis\u4e2d\u7684\u6307\u9488\u4ea4\u6362&#xff0c;\u4ea4\u6362\u5b8c\u540e\u4e34\u65f6\u5bf9\u8c61\u81ea\u5df1\u9500\u6bc1\u2014\u2014\u6b64\u65f6\u5c31\u76f8\u5f53\u4e8e\u539f\u672c\u7684\u5185\u5b58\u88ab\u91ca\u653e\u4e86\u2014\u2014\u76f8\u5f53\u4e8e\u539f\u672c\u96be\u9053\u7a7a\u95f4\u88ab\u91ca\u653e\u4e86<br \/>\n            Any(val).swap(*this);<br \/>\n            return *this;<br \/>\n        }<\/p>\n<p>        \/\/\u8fd4\u56de\u503c\u4e3a&amp;\u662f\u56e0\u4e3a\u91cd\u590d\u8d4b\u503c\u65f6\u907f\u514d\u4e0d\u5fc5\u8981\u7684\u62f7\u8d1d<br \/>\n        Any&amp; operator&#061;(const Any&amp; other){<br \/>\n            Any(other).swap(*this);<br \/>\n            return *this;<br \/>\n        }<br \/>\n}; <\/p>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u76ee\u7684\u662f\u8ba9\u4e00\u4e2aAny\u5bf9\u8c61\u5c31\u53ef\u4ee5\u4fdd\u5b58\u4efb\u610f\u7c7b\u578b\u7684\u6570\u636e\u3002\u5728Any\u7c7b\u4e2d\u4fdd\u5b58\u4e00\u4e2a\u7236\u7c7b\u6307\u9488&#xff0c;\u5229\u7528\u7236\u7c7b\u6307\u9488\u53ef\u4ee5\u6307\u5411\u5b50\u7c7b\u6307\u9488\u7684\u591a\u6001\u7279\u6027&#xff0c;\u5b50\u7c7b\u8bbe\u7f6e\u6210\u4e00\u4e2a\u6a21\u7248\u7c7b&#xff0c;\u6765\u4fdd\u5b58\u6307\u5b9a\u7684\u6570\u636e\u7c7b\u3002\u8fd9\u6837\u5c31\u5b9e\u4e60\u4e86Any\u7c7b\u6307\u5411\u4efb\u610f\u7c7b\u578b\u7684\u6570\u636e\u64cd\u4f5c\u4e86&#xff0c;\u5728\u4fdd\u5b58\u6570\u636e\u65f6&#xff0c;Any\u4f1a\u6839\u636e\u6784\u9020\u51fd\u6570\u63a8\u5bfc\u5b58\u7684\u6570\u636e\u7c7b\u578b&#xff0c;\u5728\u8bfb\u53d6\u6570\u636e\u65f6\u4f1a\u4f7f\u7528get\u51fd\u6570\u4f20\u5165\u7c7b\u578b\u53c2\u6570\u5b89\u5168\u7684\u8bfb\u53d6\u8bfb\u53d6\u6570\u636e\u3002\u76f8\u6bd4\u4e8e\u76f4\u63a5\u4f7f\u7528void* \u8fd9\u6837\u66f4\u52a0\u7b26\u5408\u73b0\u4ee3C&#043;&#043;\u7684\u8bbe\u8ba1\u601d\u8def&#xff1a;\u5b89\u5168&#xff0c;\u62bd\u8c61&#xff0c;\u6613\u7528\u3002<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Any\u7c7b\u7684\u8bbe\u8ba1&#xff1a;\u7236\u7c7b\u7684\u8bbe\u8ba1&#xff1a;\u53ea\u9700\u8981\u8bbe\u8ba1\u865a\u865a\u6784\u51fd\u6570&#xff0c;\u865a\u7c7b\u578b\u8fd4\u56de\u51fd\u6570\u548c\u865a\u5b50\u7c7b\u514b\u9686\u51fd\u6570(\u4e3a\u4e86\u4f7f\u7528\u62f7\u8d1d\u6784\u9020\u51fd\u6570)\u3002\u5b50\u7c7b\u7684\u8bbe\u8ba1&#xff1a;\u53ea\u9700\u8981\u5b50\u7c7b\u53bb\u91cd\u5199\u865a\u51fd\u6570\u5c31\u884c\u4e86\u3002\u5728\u5916\u90e8\u7c7b\u4e5f\u5c31\u662fAny\u7c7b\u4e2d\u521d\u6b65\u7684\u6784\u9020\u51fd\u6570\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u4ee5\u53ca\u865a\u6784\u51fd\u6570\u662f\u5fc5\u8981\u7684\u3002\u7136\u540e\u5c31\u662f\u83b7\u53d6Any\u7c7b\u4e2d\u7684\u6570\u636e\u7684\u51fd\u6570get&#xff0c;\u4ee5\u53ca\u5404\u79cd\u5bf9\u4e8eAny\u4e2d\u7684\u6570\u636e\u4ea4\u6362\u51fd\u6570&#xff0c;\u6bd4\u5982swap&#xff0c;operator&#061;(\u8d4b\u503c\u8fd0\u7b97\u7b26\u91cd\u8f7d)&#xff0c;\u5176\u4e2d\u4f7f\u7528\u7684\u662f\u6df1\u62f7\u8d1d\u3002<\/p>\n<h4 style=\"background-color:transparent\">4.1.3 Buffer\u7c7b\u2014\u2014\u8bfb\u5199\u7f13\u51b2\u533a<\/h4>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u4e3a\u4e86\u65b9\u4fbf\u6211\u4eec\u5904\u7406\u6570\u636e&#xff0c;\u4e0d\u4f7f\u7528\u539f\u751f\u7684I\/O\u7f13\u51b2\u533a&#xff0c;\u539f\u751fI\/O\u7f13\u51b2\u533a\u9996\u5148\u6211\u4eec\u4e0d\u80fd\u76f4\u63a5\u64cd\u4f5c&#xff0c;\u5176\u6b21\u539f\u751f\u7f13\u51b2\u533a\u5927\u5c0f\u6709\u9650&#xff0c;\u800c\u4e14\u53ef\u4ee5\u907f\u514dTCP\u7684\u7c98\u5305\/\u62c6\u5305\u95ee\u9898\u3002\u6240\u4ee5\u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e9b\u96be\u70b9\u6211\u4eec\u4f7f\u7528Buffer\u6765\u505a\u4e00\u5c42\u5e94\u7528\u5c42\u7684\u7f13\u51b2\u533a&#xff0c;\u628aI\/O\u7f13\u51b2\u533a\u62ff\u4e0a\u6765\u505a\u5c01\u88c5\u3002\u4ee3\u7801\u5982\u4e0b:<\/p>\n<p>\/\/\u670d\u52a1\u5668\u4e1a\u52a1\u7f13\u51b2\u533a\u2014\u2014\u5c06IO\u7f13\u51b2\u533a\u62ff\u5230\u4e1a\u52a1\u7f13\u51b2\u533a\u505a\u5904\u7406<br \/>\n#define BUFFER_DEFAULT_SIZE 1024<br \/>\nclass Buffer{<br \/>\n    private:<br \/>\n        std::vector&lt;char&gt; _buffer;<br \/>\n        uint64_t _reader_idx;<br \/>\n        uint64_t _writer_idx;<br \/>\n    public:<br \/>\n        Buffer():_buffer(BUFFER_DEFAULT_SIZE),_reader_idx(0),_writer_idx(0){}<br \/>\n        char *Begin(){return &amp;*_buffer.begin();}<br \/>\n        \/\/\u83b7\u53d6\u5f53\u524d\u5199\u5165\/\u8bfb\u51fa\u7684\u8d77\u59cb\u5730\u5740,_buffer\u7684\u7a7a\u95f4\u7684\u8d77\u59cb\u5730\u5740&#xff0c;\u52a0\u4e0a\u504f\u79fb\u91cf<br \/>\n        char* WritePosition(){return Begin()&#043;_writer_idx;}<br \/>\n        char*  ReadPosition(){return Begin()&#043;_reader_idx;}<br \/>\n        \/\/\u83b7\u53d6\u7f13\u51b2\u533a\u5199\u4f4d\u7f6e\u4e4b\u540e\/\u8bfb\u4f4d\u7f6e\u4e4b\u524d\u7684\u7a7a\u95f2\u7a7a\u95f4\u5927\u5c0f<br \/>\n        \/\/ \u5982\u679c\u53d1\u751f\u4e86\u6269\u5bb9 &#xff0c;\u8fd9\u91cc\u7684\u5bb9\u91cf\u8ba1\u7b97\u5c31\u662f\u9519\u8bef\u7684<br \/>\n        \/\/ uint64_t TailIdleSize(){return BUFFER_DEFAULT_SIZE-_writer_idx;}<br \/>\n        uint64_t TailIdleSize(){return _buffer.size() &#8211; _writer_idx;}<br \/>\n        uint64_t HeadIdleSize(){return _reader_idx;}<br \/>\n        \/\/\u83b7\u53d6\u7f13\u51b2\u533a\u53ef\u8bfb\u6570\u636e\u5927\u5c0f<br \/>\n        uint64_t ReadAbleSize(){<br \/>\n            \/\/ \/\/\u8fd9\u4e00\u6b65\u662f\u8003\u8651\u73af\u5f62\u7ed3\u6784\u662f\u5fc5\u987b\u7684&#xff0c;\u4f46\u662f\u6211\u8fd9\u91cc\u4e0d\u662f\u73af\u5f62\u7ed3\u6784&#xff0c;\u8fd9\u6bb5\u4ee3\u7801\u53ef\u6709\u53ef\u65e0\u3002<br \/>\n            \/\/ assert(_reader_idx&lt;&#061;_writer_idx);<br \/>\n            return _writer_idx-_reader_idx;<br \/>\n        }<\/p>\n<p>        \/\/\u5c06\u8bfb\/\u5199\u504f\u79fb\u91cf\u540e\u79fb<br \/>\n        void MoveReadOffset(uint64_t len){<br \/>\n            if(len &#061;&#061; 0)return;<br \/>\n            assert(len&lt;&#061;ReadAbleSize());<br \/>\n            _reader_idx&#043;&#061;len;<br \/>\n        }<br \/>\n        void MoveWriteOffset(uint64_t len){<br \/>\n            assert(len&lt;&#061;TailIdleSize());<br \/>\n            _writer_idx&#043;&#061;len;<br \/>\n        }<br \/>\n        \/\/\u786e\u4fdd\u53ef\u5199\u7a7a\u95f4\u8db3\u591f&#xff0c;\u9996\u5148\u8981\u58f0\u660e\u7684\u662f\u8fd9\u91cc\u7684\u6570\u636e\u7f13\u51b2\u533a\u4e0d\u662f\u73af\u5f62\u7ed3\u6784\u3002<br \/>\n        void EnsureWriteSpace(uint64_t len){<br \/>\n            if(TailIdleSize() &gt;&#061; len){return;\/*\u6b64\u65f6\u53ef\u5199\u7a7a\u95f4\u8db3\u591f*\/}<\/p>\n<p>            if(len&lt;&#061;TailIdleSize()&#043;HeadIdleSize()){<br \/>\n                \/\/\u5c06\u6570\u636e\u524d\u79fb&#xff0c;\u7528\u5230copy\u51fd\u6570<br \/>\n                uint64_t temp&#061;ReadAbleSize();<br \/>\n                auto dest&#061;ReadPosition();<br \/>\n                std::copy(dest,dest&#043;temp,Begin());<\/p>\n<p>                _reader_idx&#061;0;\/\/\u5c06\u8bfb\u504f\u79fb\u7f6e\u4e3a0&#xff0c;\u4ece\u5934\u5f00\u59cb<br \/>\n                _writer_idx&#061;temp;\/\/\u5c06\u5199\u504f\u79fb\u91cf\u7f6e\u4e3a\u6570\u636e\u957f\u5ea6<br \/>\n            }<br \/>\n            else{<br \/>\n                \/\/\u6269\u5bb9<br \/>\n                _buffer.resize(_writer_idx&#043;len);<br \/>\n            }<br \/>\n        }<br \/>\n        \/\/\u5199\u5165\u6570\u636e\u2014\u2014\u8d77\u59cb\u5c31\u662f\u62f7\u8d1d<br \/>\n        void Write(const void* data,uint64_t len){<br \/>\n            \/\/1.\u5224\u65ad\u7a7a\u95f4\u30022.\u62f7\u8d1d\u6570\u636e<br \/>\n            if(len &#061;&#061; 0)return;<br \/>\n            EnsureWriteSpace(len);<br \/>\n            \/\/void* \u662f\u6ca1\u6709\u6b65\u957f\u7684<br \/>\n            const char*d&#061;(const char*)data;<br \/>\n            std::copy(d,d&#043;len,WritePosition());<br \/>\n            \/\/\u540c\u6837\u8fd9\u91cc\u4e5f\u5206\u5f00\u5199&#xff0c;\u5b9e\u73b0\u4e24\u4e2aAPI-\u5199\u5165\u4e0d\u79fb\u52a8&#xff0c;\u5199\u5165\u79fb\u52a8<br \/>\n            \/\/ MoveWriteOffset(len);<br \/>\n        }<br \/>\n        void WriteAndPush(const void* data,uint64_t len){<br \/>\n            Write(data,len);<br \/>\n            MoveWriteOffset(len);<br \/>\n        }<\/p>\n<p>        void WriteString(std::string &amp;data){Write(data.c_str(),data.size());}<br \/>\n        void WriteStringAndPush(std::string &amp;data){<br \/>\n            WriteString(data);<br \/>\n            MoveWriteOffset(data.size());<br \/>\n        }<\/p>\n<p>        void WriteBuffer(Buffer&amp; data){Write(data.ReadPosition(),data.ReadAbleSize());}<br \/>\n        void WriteBufferAndPush(Buffer&amp; data){<br \/>\n            WriteBuffer(data);<br \/>\n            MoveWriteOffset(data.ReadAbleSize());<br \/>\n        }<\/p>\n<p>        \/\/\u8bfb\u6570\u636e-\u4e0d\u79fb\u52a8\u6307\u9488<br \/>\n        void Read(void *buf,uint64_t len){<br \/>\n            \/\/\u786e\u4fdd\u53ef\u8bfb<br \/>\n            assert(len&lt;&#061;ReadAbleSize());<br \/>\n            std::copy(ReadPosition(),ReadPosition()&#043;len,(char*)buf);<\/p>\n<p>            \/\/\u4e24\u4e2a\u51fd\u6570\u5206\u5f00\u5199<br \/>\n            \/\/ MoveReadOffset(len);<br \/>\n        }<br \/>\n        \/\/\u8bfb\u6570\u636e-\u79fb\u52a8\u6307\u9488<br \/>\n        void ReadAndPop(void *buf,uint64_t len){<br \/>\n            Read(buf,len);<br \/>\n            MoveReadOffset(len);<br \/>\n        }<br \/>\n        std::string ReadAsStirng(uint64_t len){<br \/>\n            assert(len&lt;&#061;ReadAbleSize());<br \/>\n            \/\/string::c_str()\u2014\u2014\u8fd9\u8fd4\u56de\u7684\u662f\u4e00\u4e2aconst char*\u7684\u7c7b\u578b<br \/>\n            std::string s;<br \/>\n            s.resize(len);<br \/>\n            Read(&amp;s[0],s.size());<br \/>\n            return s;<br \/>\n        }<br \/>\n        std::string ReadAsStirngAndPop(uint64_t len){<br \/>\n            assert(len&lt;&#061;ReadAbleSize());<br \/>\n            std::string s &#061; ReadAsStirng(len);<br \/>\n            MoveReadOffset(len);<br \/>\n            return s;<br \/>\n        }<br \/>\n        \/\/\u5728tcp\u4e2d\u8fd8\u6709\u4e00\u4e2a\u529f\u80fd\u5c31\u662f\u4e00\u6b21\u8bfb\u53d6\u4e00\u884c\u6570\u636e\u2014\u2014\u8bf4\u767d\u4e86\u8fd9\u5c31\u662f\u5bf9tcp\u7f13\u51b2\u533a\u7684\u4e00\u6b21\u91cd\u65b0\u5c01\u88c5&#xff0c;\u6ee1\u8db3\u6211\u4eec\u7684\u9700\u6c42<br \/>\n        char* FindCRLF(){<br \/>\n            char * res &#061; static_cast&lt;char*&gt;(memchr(ReadPosition(),&#039;\\\\n&#039;,ReadAbleSize()));<br \/>\n            return res;<br \/>\n        }<\/p>\n<p>        std::string GetLine(){<br \/>\n            char* pos &#061; FindCRLF();<br \/>\n            if(pos &#061;&#061; nullptr){<br \/>\n                return &#034;&#034;;<br \/>\n            }<br \/>\n            return ReadAsStirng(pos-ReadPosition()&#043;1);<br \/>\n        }<br \/>\n        std::string GetLineAndPop(){<br \/>\n            std::string str &#061; GetLine();<br \/>\n            MoveReadOffset(str.size());<br \/>\n            return str;<br \/>\n        }<br \/>\n        \/\/\u6e05\u7a7a\u7f13\u51b2\u533a<br \/>\n        void Clear(){<br \/>\n            _reader_idx&#061;0;<br \/>\n            _writer_idx&#061;0;<br \/>\n        }<br \/>\n};<\/p>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u5728\u7f13\u51b2\u533a\u5927\u5c0f\u8fd9\u91cc\u6211\u9ed8\u8ba4\u8bbe\u7f6e\u6210\u4e861024&#xff0c;\u8fd9\u91cc\u6ce8\u610f\u6570\u5b57\u4e00\u5b9a\u8981\u5f04\u6210\u5b8f\u5b9a\u4e49&#xff0c;\u4e0d\u7136\u5c31\u4f1a\u51fa\u73b0\u4e00\u5806\u7684\u9b54\u5e7b\u6570\u5b57&#xff0c;\u589e\u5927\u4e86\u540e\u671f\u7ef4\u62a4\u4fee\u6539\u7684\u96be\u5ea6\u3002\u5728\u7f13\u51b2\u533a\u5bb9\u5668\u4e2d\u4f7f\u7528vector\u56e0\u4e3a\u5176\u7ebf\u6027\u7684\u6570\u636e\u8bbf\u95ee\u7279\u6027\u53ef\u4ee5\u52a0\u5927\u8bfb\u53d6\u6548\u7387&#xff0c;\u4e5f\u65b9\u4fbf\u6211\u4eec\u6269\u5bb9&#xff0c;\u4f7f\u7528\u4e24\u4e2a\u6307\u9488(\u6574\u5f62\u4e0b\u6807)\u53bb\u4fdd\u5b58\u5199\u6570\u636e\u4e0b\u6807\u548c\u8bfb\u6570\u636e\u4e0b\u6807\u3002\u8fd9\u6837\u5c31\u591f\u4e86\u3002\u63a5\u7740\u5c31\u662f\u5bf9\u5916\u5f00\u653e\u7684\u5904\u7406\u7f13\u51b2\u533a\u7684\u51fd\u6570&#xff0c;\u6bd4\u5982&#xff1a;\u83b7\u53d6\u5269\u4f59\u7f13\u51b2\u533a\u7a7a\u95f4\u3001\u83b7\u53d6\u8bfb\u4f4d\u7f6e\u3001\u83b7\u53d6\u5199\u4f4d\u7f6e\u3001\u5199\u6570\u636e\u3001\u8bfb\u6570\u636e\u3001\u6269\u5bb9\u51fd\u6570\u3001\u6e05\u7a7a\u7f13\u51b2\u533a\u3001\u4ee5\u53ca\u4e3a\u4e86http\u670d\u52a1\u5668\u5904\u7406\u53c2\u6570\u989d\u5916\u8bbe\u7f6e\u4e86\u8bfb\u53d6\u4e00\u884c\u6570\u636e\u7684\u63a5\u53e3\u7b49\u3002<\/p>\n<h3>4.2 \u7f51\u7edc\u57fa\u7840\u6a21\u5757<\/h3>\n<h4>4.2.1 Socket\u7c7b\u2014\u2014\u539f\u751fAPI\u5c01\u88c5<\/h4>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u8fd9\u4e2a\u7c7b\u5c31\u662f\u5bf9Socket\u7684\u539f\u751f\u5c01\u88c5&#xff0c;\u5728Socket\u7684\u57fa\u7840\u4e0a\u628a\u53d1\u9001\u548c\u63a5\u6536\u6570\u636e\u4ee5\u53ca\u521b\u5efa\u5ba2\u6237\u7aef\u8fde\u63a5\u548c\u670d\u52a1\u5668\u8fde\u63a5\u76f4\u63a5\u96c6\u6210\u5728\u4e86\u8fd9\u4e2a\u7c7b\u4e2d\u3002\u4ee3\u7801\u5982\u4e0b&#xff1a;<\/p>\n<p>class Socket{<br \/>\n    private:<br \/>\n        \/\/\u521b\u5efa\u76d1\u542c\u5957\u63a5\u5b57<br \/>\n        int _sockfd;<br \/>\n    public:<br \/>\n        Socket():_sockfd(-1){}<br \/>\n        Socket(int fd):_sockfd(fd){}<br \/>\n        ~Socket(){Close();}<br \/>\n        int Fd() { return _sockfd; }<br \/>\n        \/\/\u521b\u5efa\u5957\u63a5\u5b57<br \/>\n        bool Create(){<br \/>\n            \/\/int socket(int domain,int type,int protocol);<br \/>\n            _sockfd&#061;socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);<br \/>\n            if(_sockfd&lt;0){<br \/>\n                ERR_LOG(&#034;Create \u76d1\u542c\u5957\u63a5\u5b57\u5931\u8d25&#xff01;&#xff01;&#xff01;&#034;);<br \/>\n                return false;<br \/>\n            }<br \/>\n            return true;<br \/>\n        }<br \/>\n        \/\/\u7ed1\u5b9a\u5730\u5740\u4fe1\u606f<br \/>\n        bool Bind(const std::string&amp; ip ,uint16_t port){<br \/>\n            \/\/\u521b\u5efatcp<br \/>\n            struct sockaddr_in addr;<br \/>\n            addr.sin_family&#061;AF_INET;<br \/>\n            addr.sin_port&#061;htons(port);<br \/>\n            addr.sin_addr.s_addr&#061;inet_addr(ip.c_str());<br \/>\n            socklen_t len&#061;sizeof(struct sockaddr_in);<br \/>\n            \/\/ int ret &#061; bind(_sockfd,reinterpret_cast&lt;struct sockaddr*&gt;(&amp;addr),len);<br \/>\n            int ret &#061; bind(_sockfd, (struct sockaddr*)&amp;addr, len);<br \/>\n            if(ret&lt;0){<br \/>\n                ERR_LOG(&#034;Bind \u5931\u8d25&#xff01;&#xff01;&#xff01;&#xff01;&#034;);<br \/>\n                return false;<br \/>\n            }<br \/>\n            return true;<br \/>\n        }<br \/>\n        \/\/\u5f00\u59cb\u76d1\u542c<br \/>\n        bool Listen(int backlog &#061; MAX_LISTEN){<br \/>\n            \/\/int listen(int backlog)<br \/>\n            int ret &#061; listen(_sockfd,backlog);<br \/>\n            if(ret&lt;0){<br \/>\n                ERR_LOG(&#034;Listen \u5931\u8d25&#xff01;&#xff01;&#xff01;&#xff01;&#034;);<br \/>\n                return false;<br \/>\n            }<br \/>\n            return true;<br \/>\n        }<br \/>\n        \/\/\u5411\u670d\u52a1\u5668\u53d1\u8d77\u8fde\u63a5<br \/>\n        bool Connect(const std::string&amp;ip ,uint16_t port){<br \/>\n            struct sockaddr_in addr;<br \/>\n            addr.sin_family&#061;AF_INET;<br \/>\n            addr.sin_port&#061;htons(port);<br \/>\n            addr.sin_addr.s_addr&#061;inet_addr(ip.c_str());<br \/>\n            socklen_t len&#061;sizeof(struct sockaddr_in);<br \/>\n            \/\/ int ret &#061; connect(_sockfd,reinterpret_cast&lt;struct sockaddr*&gt;(&amp;addr),len);<br \/>\n            int ret &#061; connect(_sockfd,(struct sockaddr*)&amp;addr,len);<\/p>\n<p>            if(ret&lt;0){<br \/>\n                ERR_LOG(&#034;Connect \u5931\u8d25&#xff01;&#xff01;&#xff01;&#xff01;&#034;);<br \/>\n                return false;<br \/>\n            }<br \/>\n            return true;<br \/>\n        }<br \/>\n        int Accept(){<br \/>\n            \/\/int accept(int sockfd,struct sockaddr* addr, socklen_t* len);<br \/>\n            int newfd &#061; accept(_sockfd,nullptr,nullptr);<br \/>\n            if(newfd&lt;0){<br \/>\n                ERR_LOG(&#034;Accept \u5931\u8d25&#xff01;&#xff01;&#xff01;%s&#034;,strerror(errno));<br \/>\n                return -1;<br \/>\n            }<br \/>\n            return newfd;<br \/>\n        }<br \/>\n        ssize_t Recv(void*buf,size_t len,int flag&#061;0){<br \/>\n            ssize_t ret &#061; recv(_sockfd,buf,len,flag);<br \/>\n            if(ret&lt;&#061;0){<br \/>\n                if(errno &#061;&#061; EAGAIN || errno &#061;&#061; EINTR){<br \/>\n                    ERR_LOG(&#034;\u4fe1\u53f7\u4e2d\u65ad\/\u6ca1\u6570\u636e&#034;);<br \/>\n                    return 0;<br \/>\n                    \/\/EAGAIN\u2014\u2014\u975e\u963b\u585e\u6ca1\u6570\u636e\u4e86<br \/>\n                    \/\/EINTR\u2014\u2014\u963b\u585e&#xff0c;\u88ab\u4fe1\u53f7\u4e2d\u65ad\u4e86<br \/>\n                }<br \/>\n                return -1;<br \/>\n            }<br \/>\n            return ret;<br \/>\n        }<br \/>\n        ssize_t NonBlockRecv(void*buf,size_t len){return Recv(buf,len,MSG_DONTWAIT);}<\/p>\n<p>        ssize_t Send(const void*buf,size_t len,int flag&#061;0){<br \/>\n            ssize_t ret &#061; send(_sockfd,buf,len,flag);<br \/>\n            if(ret&lt;0){<br \/>\n                if(errno &#061;&#061; EAGAIN || errno &#061;&#061; EINTR){<br \/>\n                    ERR_LOG(&#034;\u4fe1\u53f7\u4e2d\u65ad\/\u6ca1\u6570\u636e&#034;);<br \/>\n                    return 0;<br \/>\n                    \/\/EAGAIN\u2014\u2014\u975e\u963b\u585e\u6ca1\u6570\u636e\u4e86<br \/>\n                    \/\/EINTR\u2014\u2014\u963b\u585e&#xff0c;\u88ab\u4fe1\u53f7\u4e2d\u65ad\u4e86<br \/>\n                }<br \/>\n                ERR_LOG(&#034;Send \u5931\u8d25&#xff01;&#xff01;&#xff01;&#xff01;&#034;);<br \/>\n                return -1;<br \/>\n            }<br \/>\n            return ret;<br \/>\n        }<br \/>\n        \/\/MSG_DONTWAIT<br \/>\n        ssize_t NonBlockSend(const void*buf,size_t len){ if (len &#061;&#061; 0) return 0;return Send(buf,len,MSG_DONTWAIT);}<br \/>\n        \/\/\u5173\u95ed\u5957\u63a5\u5b57<br \/>\n        void Close(){<br \/>\n            if(_sockfd!&#061;-1){<br \/>\n                close(_sockfd);<br \/>\n                _sockfd&#061;-1;<br \/>\n            }<br \/>\n        }<br \/>\n        \/\/\u521b\u5efa\u4e00\u4e2a\u670d\u52a1\u5668\u8fde\u63a5<br \/>\n        bool CreateServer(uint16_t port,const std::string&amp;ip&#061;&#034;0.0.0.0&#034;,bool blog_flag&#061;false){<br \/>\n            \/\/1.\u521b\u5efa\u76d1\u542c\u5957\u63a5\u5b57 2.\u8bbe\u7f6e\u975e\u963b\u585e  3.\u7ed1\u5b9a\u5957\u63a5\u5b57  4.\u5f00\u59cb\u76d1\u542c 5.\u542f\u52a8\u5730\u5740\u91cd\u7528<br \/>\n            if(!Create())return false;<br \/>\n            if(blog_flag)NonBlock();<br \/>\n            if(!Bind(ip,port))return false;<br \/>\n            if(!Listen())return false;<br \/>\n            ReuseAddress();<br \/>\n            return true;<br \/>\n        }<br \/>\n        \/\/\u521b\u5efa\u4e00\u4e2a\u5ba2\u6237\u7aef\u8fde\u63a5<br \/>\n        bool CreateClient(uint16_t port,const std::string&amp;ip){<br \/>\n            \/\/1.\u521b\u5efa\u8fde\u63a5\u5957\u63a5\u5b57  2.\u8fde\u63a5\u670d\u52a1\u5668<br \/>\n            if(!Create())return false;<br \/>\n            if(!Connect(ip,port))return false;<br \/>\n            return true;<br \/>\n        }<br \/>\n        \/\/\u8bbe\u7f6e\u5957\u63a5\u5b57\u9009\u9879&#8212;\u5f00\u542f\u5730\u5740\u7aef\u53e3\u7684\u91cd\u7528<br \/>\n        void ReuseAddress(){<br \/>\n            \/\/int setsockopt(int fd,int leve , int optname , void * val,int vallen)<br \/>\n            int val &#061; 1;<br \/>\n            setsockopt(_sockfd,SOL_SOCKET , SO_REUSEADDR , (void*)&amp;val ,sizeof(int));<br \/>\n            val &#061; 1;<br \/>\n            setsockopt(_sockfd,SOL_SOCKET , SO_REUSEPORT , (void*)&amp;val ,sizeof(int));<br \/>\n        }<br \/>\n        \/\/\u8bbe\u7f6e\u5957\u63a5\u5b57\u963b\u585e\u5c5e\u6027&#8212;\u8bbe\u7f6e\u4e3a\u975e\u963b\u585e<br \/>\n        void NonBlock(){<br \/>\n            \/\/int fcntl(int fd , int cmd ,&#8230;..\/*arg*\/);<br \/>\n            int flag &#061; fcntl(_sockfd,F_GETFL,0);<br \/>\n            fcntl(_sockfd,F_SETFL,flag | O_NONBLOCK);<br \/>\n        }<br \/>\n}; <\/p>\n<h4 style=\"background-color:transparent\">4.2.2 Channel\u7c7b\u2014\u2014\u4e8b\u4ef6\u5c01\u88c5<\/h4>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 Channel\u7c7b\u5b9e\u9645\u4e0a\u5c31\u662f\u5bf9epoll\u64cd\u4f5c\u7684\u5c01\u88c5\u7c7b&#xff0c;\u529f\u80fd\u6709&#xff1a;\u542f\u52a8\u8bfb\/\u5199\u4e8b\u4ef6\u76d1\u63a7\u3001\u5173\u95ed\u8bfb\/\u5199\u4e8b\u4ef6\u76d1\u63a7\u3001\u662f\u5426\u76d1\u63a7\u4e86\u8bfb\/\u5199\u4e8b\u4ef6\u3001\u4ee5\u53ca\u5bf9\u5c31\u7eea\u4e8b\u4ef6\u7684\u5904\u7406\u3002\u4ee3\u7801\u5982\u4e0b&#xff1a;<\/p>\n<p>\/\/epoll\u6a21\u5f0fLT\u6a21\u5f0f-\u6c34\u5e73\u89e6\u53d1<br \/>\n\/\/\u8bbe\u7f6e\u7ba1\u7406\u4e8b\u4ef6\u76d1\u63a7&#xff0c;\u5199\u4e8b\u4ef6\u8fd8\u662f\u8bfb\u4e8b\u4ef6&#xff0c;\u4e00\u4e2a\u8fde\u63a5\u5bf9\u5e94\u4e00\u4e2aChannel\u7c7b<br \/>\n#include &lt;sys\/epoll.h&gt;  \/\/ \u5305\u542bEPOLLIN\u7b49epoll\u4e8b\u4ef6\u6807\u5fd7\u7684\u5b9a\u4e49<br \/>\nclass Channel{<br \/>\n    private:<br \/>\n        int _fd;<br \/>\n        EventLoop* _loop;<br \/>\n        uint32_t _events; \/\/ \u5f53\u524d\u9700\u8981\u76d1\u63a7\u7684\u4e8b\u4ef6<br \/>\n        uint32_t _revents;\/\/ \u5f53\u524d\u76d1\u63a7\u4e8b\u4ef6\u7684\u5c31\u7eea\u4e8b\u4ef6<br \/>\n        using EventCallback &#061; std::function&lt;void()&gt;;<br \/>\n        EventCallback _read_callback; \/\/\u53ef\u8bfb\u4e8b\u4ef6\u88ab\u5904\u7f5a\u7684\u56de\u8c03\u51fd\u6570<br \/>\n        EventCallback _write_callback;\/\/\u53ef\u5199\u4e8b\u4ef6\u88ab\u5904\u7f5a\u7684\u56de\u8c03\u51fd\u6570<br \/>\n        EventCallback _error_callback;\/\/\u9519\u8bef\u4e8b\u4ef6\u88ab\u5904\u7f5a\u7684\u56de\u8c03\u51fd\u6570<br \/>\n        EventCallback _close_callback;\/\/\u8fde\u63a5\u65ad\u5f00\u4e8b\u4ef6\u88ab\u5904\u7f5a\u7684\u56de\u8c03\u51fd\u6570<br \/>\n        EventCallback _event_callback;\/\/\u4efb\u610f\u4e8b\u4ef6\u88ab\u5904\u7f5a\u7684\u56de\u8c03\u51fd\u6570<br \/>\n    public:<br \/>\n        Channel(EventLoop* loop,int fd):_fd(fd),_loop(loop),_events( 0),_revents(0) {}<br \/>\n        int Fd(){return _fd;}<br \/>\n        uint32_t Events(){return _events;}\/\/\u83b7\u53d6\u76d1\u63a7\u4e8b\u4ef6<br \/>\n        void SetRevents(uint32_t events){_revents&#061;events;}\/\/\u8bbe\u7f6e\u5b9e\u9645\u5c31\u7eea\u7684\u4e8b\u4ef6<br \/>\n        void SetReadCallback(const EventCallback&amp; cb){_read_callback&#061;cb;}<br \/>\n        void SetWriteCallback(const EventCallback&amp; cb){_write_callback&#061;cb;}<br \/>\n        void SetErrorCallback(const EventCallback&amp; cb){_error_callback&#061;cb;}<br \/>\n        void SetCloseCallback(const EventCallback&amp; cb){_close_callback&#061;cb;}<br \/>\n        void SetEventCallback(const EventCallback&amp; cb){_event_callback&#061;cb;}<br \/>\n        \/\/\u5f53\u524d\u662f\u5426\u76d1\u63a7\u4e86\u53ef\u8bfb<br \/>\n        bool ReadAble(){return _events &amp; EPOLLIN;\/*\u5c31\u662f\u770b\u6211\u5f53\u524d\u76d1\u63a7\u7684\u4e8b\u4ef6\u4e2d\u662f\u5426\u76d1\u63a7\u4e86\u53ef\u8bfb\u4e8b\u4ef6\u5c31\u662f\u53bb\u6309\u4f4d\u4e0e\u4e00\u4e0b*\/}<br \/>\n        \/\/\u5f53\u524d\u662f\u5426\u76d1\u63a7\u4e86\u53ef\u5199,\u8fd9\u91cc\u5904\u7406\u5728LT\u6a21\u5f0f\u4e0b\u9632\u6b62\u591a\u6b21\u7684\u8bbe\u7f6e\u53ef\u8bfb\u53ef\u5199\u5bfc\u81f4\u7684LoopBusy<br \/>\n        bool WriteAble(){return _events &amp; EPOLLOUT;}<br \/>\n        \/\/\u542f\u52a8\u8bfb\u4e8b\u4ef6\u76d1\u63a7 \u8fd9\u53ea\u662f\u8bbe\u7f6e\u4e86_event\u8fd8\u5e76\u6ca1\u6709\u8bbe\u7f6e\u5230epoll\u4e2d\u53bb<br \/>\n        void EnableRead(){_events |&#061; EPOLLIN; Update();}<br \/>\n        \/\/\u542f\u52a8\u5199\u4e8b\u4ef6\u76d1\u63a7<br \/>\n        void EnableWrite(){_events |&#061; EPOLLOUT; Update();}<br \/>\n        \/\/\u5173\u95ed\u8bfb\u4e8b\u4ef6\u76d1\u63a7<br \/>\n        void DisableRead(){_events &amp;&#061; ~EPOLLIN; Update();}<br \/>\n        \/\/\u5173\u95ed\u5199\u4e8b\u4ef6\u76d1\u63a7<br \/>\n        void DisableWrite(){_events &amp;&#061; ~EPOLLOUT; Update();}<br \/>\n        \/\/\u5173\u95ed\u6240\u6709\u4e8b\u4ef6\u76d1\u63a7<br \/>\n        void DisableAll(){_events&#061;0;}<br \/>\n        \/\/\u79fb\u9664\u76d1\u63a7\u2014\u2014\u540e\u9762\u8c03\u7528EventLoop\u8c03\u7528<br \/>\n        void Remove();<br \/>\n        void Update();<br \/>\n        \/\/\u4e8b\u4ef6\u5904\u7406&#xff0c;\u4e00\u65e6\u8fde\u63a5\u89e6\u53d1\u4e86\u4e8b\u4ef6&#xff0c;\u5c31\u8c03\u7528\u8fd9\u4e2a\u51fd\u6570&#xff0c;\u7136\u540e\u770b_revnet\u89e6\u53d1\u4e86\u54ea\u4e00\u4e2a\u4e8b\u4ef6&#xff0c;\u7136\u540e\u5185\u90e8\u8c03\u7528\u4e0d\u540c\u7684\u56de\u8c03<br \/>\n        \/\/\u81ea\u5df1\u89e6\u53d1\u4e86\u4ec0\u4e48\u4e8b\u4ef6\u81ea\u5df1\u5904\u7406&#xff0c;EventLoop\u4e0d\u5173\u5fc3&#xff0c;\u6211\u53ea\u7ba1\u8c03\u7528HanleEvent\u2014\u2014\u672c\u8d28\u5c31\u662f\u8fdb\u884c\u4e86\u4e00\u5c42\u5c01\u88c5\u561b&#xff0c;\u770b\u662f\u5c01\u88c5\u5230\u54ea\u4e00\u5c42\u4e86\u3002<br \/>\n        void HandleEvent(){<br \/>\n            \/\/\u89e6\u53d1\u8fde\u63a5\u65ad\u5f00\u4e5f\u5c31\u662f\u534a\u5173\u95ed\u8fde\u63a5EPOLLRDHUP(\u5bf9\u65b9\u5173\u95ed\u8fde\u63a5)&#xff0c;\u90a3\u4e48\u6211\u4eec\u5c31\u8981\u628a\u7f13\u51b2\u533a\u7684\u6570\u636e\u8bfb\u5b8c<br \/>\n            if((_revents &amp; EPOLLIN) || (_revents &amp; EPOLLRDHUP) || (_revents &amp; EPOLLPRI)){<br \/>\n                \/\/ if(_read_callback)_read_callback();<br \/>\n                \/\/ if(_event_callback)_event_callback();<br \/>\n                if(_read_callback)_read_callback();<br \/>\n            }<br \/>\n            \/\/\u6709\u53ef\u80fd\u4f1a\u91ca\u653e\u8fde\u63a5\u7684\u4e8b\u4ef6&#xff0c;\u4e00\u6b21\u5904\u7406\u4e00\u4e2a<br \/>\n            if(_revents &amp; EPOLLOUT)<br \/>\n                {<br \/>\n                    \/\/\u653e\u5230\u4e8b\u4ef6\u5904\u7406\u5b8c\u6bd5\u540e\u8c03\u7528&#xff0c;\u5237\u65b0\u6d3b\u8dc3\u5ea6<br \/>\n                    \/\/ if(_write_callback)_write_callback();<br \/>\n                    \/\/ if(_event_callback)_event_callback();<br \/>\n                    if(_write_callback)_write_callback();<br \/>\n                }<br \/>\n            else if(_revents &amp; EPOLLERR)<br \/>\n                {<br \/>\n                    \/\/\u653e\u5230\u524d\u9762&#xff0c;\u56e0\u4e3a\u51fa\u9519\u76f4\u63a5\u5173\u95ed\u4e86<br \/>\n                    if(_error_callback)_error_callback();<br \/>\n                }<br \/>\n            else if(_revents &amp; EPOLLHUP)<br \/>\n                {<br \/>\n                    if(_close_callback)_close_callback();<br \/>\n                }<br \/>\n            if(_event_callback)_event_callback();<br \/>\n        }<br \/>\n}; <\/p>\n<h3 style=\"background-color:transparent\">4.3 \u4e8b\u4ef6\u9a71\u52a8\u6a21\u5757<\/h3>\n<h4>4.3.1 Poller\u7c7b\u2014\u2014\u5bf9epoll\u7684\u5c01\u88c5<\/h4>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 Poller\u7c7b\u65f6\u771f\u6b63\u5730\u5bf9epoll\u7684\u5c01\u88c5\u5185\u90e8\u6709epoll\u7684\u521b\u5efa&#xff0c;\u548c\u5bf9\u76d1\u63a7\u4e8b\u4ef6\u7684\u771f\u6b63\u4fee\u6539\u3002\u5728\u6210\u5458\u53d8\u91cf\u4e2d&#xff0c;\u6709\u4e00\u4e2a_epfd&#xff08;epoll\u7684fd\u64cd\u4f5c\u7b26&#xff09;\u4ee5\u53ca\u4e00\u4e2aepoll_event\u6570\u7ec4\u5bf9\u6240\u6709\u8fde\u63a5\u7684\u7ba1\u7406&#xff0c;\u8fd8\u6709\u4e00\u4e2a\u8fde\u63a5\u4e00\u4e2afd\u7684\u54c8\u5e0c\u5b58\u50a8\u8868&#xff0c;\u65b9\u4fbf\u67e5\u8be2\u548c\u5bf9\u5355\u4e2a\u8fde\u63a5\u64cd\u4f5c\u3002<\/p>\n<p>#define MAX_EPOLLEVENTS 1024<br \/>\n#include &lt;sys\/epoll.h&gt;<br \/>\n#include&lt;unordered_map&gt;<\/p>\n<p>\/\/epoll\u7ba1\u7406\u7c7b\u2014\u2014\u5bf9\u6240\u6709\u94fe\u63a5\u5bf9\u5e94\u7684\u6240\u6709Channel\u7c7b\u7ba1\u7406\u2014\u2014\u8fdb\u884c\u66f4\u65b0\u4fee\u6539&#xff0c;\u5f00\u542f\u4e8b\u4ef6\u76d1\u63a7\u548c\u53d6\u6d88\u76d1\u63a7\u2014\u2014\u5bf9\u6240\u6709\u670d\u52a1\u5668\u4e0a\u7684\u8fde\u63a5\u505a\u7ba1\u7406<br \/>\nclass Poller{<br \/>\n    private:<br \/>\n        int _epfd;<br \/>\n        struct epoll_event _evs[MAX_EPOLLEVENTS];<br \/>\n        std::unordered_map&lt;int,Channel*&gt; _channels;<br \/>\n    private:<br \/>\n        \/\/\u5bf9epoll\u7684\u76f4\u63a5\u64cd\u4f5c<br \/>\n        void Update(Channel *channel,int op){<br \/>\n            \/\/int epoll&#043;ctl(int epfd , int op , int fd , struct eopll_event* ev);<br \/>\n            int fd &#061; channel-&gt;Fd();<br \/>\n            struct epoll_event ev;<br \/>\n            ev.data.fd&#061;fd;<br \/>\n            \/\/\u8981\u64cd\u4f5c\u7684\u4e8b\u4ef6<br \/>\n            ev.events&#061;channel-&gt;Events();<br \/>\n            int ret &#061; epoll_ctl(_epfd,op,fd,&amp;ev);<br \/>\n            if(ret&lt;0){<br \/>\n                ERR_LOG(&#034;epoll_ctl \u5931\u8d25&#xff01;&#xff01;&#xff01;&#034;);<br \/>\n            }<br \/>\n            return ;<br \/>\n        }<br \/>\n        \/\/\u5224\u65ad\u4e00\u4e2aChannel\/\u4e00\u4e2a\u8fde\u63a5\u662f\u5426\u5df2\u7ecf\u6dfb\u52a0\u4e86\u4e8b\u4ef6\u76d1\u63a7<br \/>\n        bool HashCHannel(Channel* channel){<br \/>\n            auto it &#061; _channels.find(channel-&gt;Fd());<br \/>\n            if(it&#061;&#061;_channels.end())return false;<br \/>\n            return true;<br \/>\n        }<\/p>\n<p>    public:<br \/>\n        Poller(){<br \/>\n            _epfd &#061; epoll_create(MAX_EPOLLEVENTS);<br \/>\n            if(_epfd&lt;0){<br \/>\n                ERR_LOG(&#034;epoll_create \u5931\u8d25&#xff01;&#xff01;&#xff01;&#034;);<br \/>\n                abort();<br \/>\n            }<br \/>\n        }<br \/>\n        \/\/\u6dfb\u52a0\u6216\u4fee\u6539\u76d1\u63a7\u4e8b\u4ef6<br \/>\n        void UpdateEvent(Channel *channel){<br \/>\n            auto it &#061; _channels.find(channel-&gt;Fd());<br \/>\n            if(it&#061;&#061;_channels.end()){<br \/>\n                _channels.insert({channel-&gt;Fd(),channel});<br \/>\n                return Update(channel,EPOLL_CTL_ADD);<br \/>\n            }<br \/>\n            Update(channel,EPOLL_CTL_MOD);<br \/>\n        }<br \/>\n        \/\/\u79fb\u9664\u76d1\u63a7<br \/>\n        void RemoveEvent(Channel *channel){<br \/>\n            auto it &#061; _channels.find(channel-&gt;Fd());<br \/>\n            if(it!&#061;_channels.end()) _channels.erase(it);<br \/>\n            Update(channel,EPOLL_CTL_DEL);<br \/>\n        }<br \/>\n        \/\/\u5f00\u59cb\u76d1\u63a7&#xff0c;\u8fd4\u56de\u6d3b\u8dc3\u8fde\u63a5<br \/>\n        void Poll(std::vector&lt;Channel*&gt;* active){<br \/>\n            \/\/int epoll_wait(int epfd , struct epoll_event* evs , int maxevents , int timeout)<br \/>\n            int nfds &#061; epoll_wait(_epfd,_evs,MAX_EPOLLEVENTS,-1);\/\/-1\u4ee3\u8868\u963b\u585e\u7b49\u5f85&#xff0c;timeout&gt;&#061;0\u4ee3\u8868\u963b\u585e\u7b49\u5f85x\u79d2&#xff0c;\u8d85\u65f6\u8fd4\u56de<br \/>\n            if(nfds&lt;0){<br \/>\n                if(errno &#061;&#061; EINTR){<br \/>\n                    \/\/\u53ef\u80fd\u662f\u7531\u4e8e\u4e2d\u65ad\u6253\u65ad\u4e86epoll_wait\u51fd\u6570<br \/>\n                    return;\/\/\u6b64\u65f6\u7a0b\u5e8f\u4e0d\u9000\u51fa<br \/>\n                }<br \/>\n                ERR_LOG(&#034;epoll_wait \u5931\u8d25:%s\\\\n&#034;,strerror(errno));<br \/>\n                abort();\/\/\u9000\u51fa\u7a0b\u5e8f\u2014\u2014\u5f02\u5e38\u9000\u51fa\u6709\u8c03\u8bd5\u4fe1\u606f&#xff0c;exit\u6b63\u5e38\u9000\u51fa\u6e05\u7406\u7a0b\u5e8f<br \/>\n            }<br \/>\n            for(int i&#061;0;i&lt;nfds;&#043;&#043;i){<br \/>\n                auto it &#061; _channels.find(_evs[i].data.fd);<br \/>\n                assert(it!&#061;_channels.end());<br \/>\n                it-&gt;second-&gt;SetRevents(_evs[i].events);<br \/>\n                active-&gt;push_back(it-&gt;second);<br \/>\n            }<br \/>\n        }<br \/>\n}; <\/p>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u5176\u4e2d\u6700\u5173\u952e\u7684\u662fPoll\u51fd\u6570&#xff0c;\u5f00\u59cb\u76d1\u63a7&#xff0c;\u8fd4\u56de\u6d3b\u8dc3\u8fde\u63a5\u3002epoll_wait\u8fd4\u56de\u5c31\u7eea\u94fe\u8868\u4e2d\u7684\u4e8b\u4ef6\u6570\u91cf&#xff0c;\u6240\u4ee5\u5728\u540e\u7eed\u7684for\u5faa\u73af\u4e2d\u628a\u5c31\u7eea\u4e8b\u4ef6\u4e00\u4e00\u8bbe\u7f6e\u5230\u6bcf\u4e2a\u8fde\u63a5\u7684Channel\u4e2d\u3002<\/p>\n<h4>4.3.2 EventLoop\u7c7b\u2014\u2014Reactor\u6838\u5fc3<\/h4>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u5728EventLoop\u7c7b\u4e2d\u6700\u4e3b\u8981\u7684\u5c31\u662fStart\u51fd\u6570\u2014\u2014\u5904\u7406\u5c31\u7eea\u76d1\u63a7\u4e8b\u4ef6&#xff0c;\u6267\u884c\u4efb\u52a1\u961f\u5217\u4e2d\u7684\u4efb\u52a1\u7684\u6b7b\u5faa\u73af&#xff0c;\u5982\u679c\u6ca1\u6709\u5c31\u7eea\u76d1\u63a7\u4e8b\u4ef6\u5c31\u4f1a\u5361\u5728Poll\u4e2d&#xff0c;\u4f46\u662f\u5728\u5176\u4ed6\u7ebf\u7a0b\u538b\u5165\u4efb\u52a1\u961f\u5217\u65f6\u3001\u76d1\u63a7\u4e8b\u4ef6\u5c31\u7eea\u65f6\u6216\u8005\u5728\u670d\u52a1\u5668\u7684listen_fd\u7ba1\u7406\u7c7b\u4e2d\u65b0\u8fde\u63a5\u5230\u6765\u65f6&#xff0c;\u5c31\u4e0d\u5728\u963b\u585e\u672c\u8d28\u5c31\u662f\u6709\u76d1\u63a7\u4e8b\u4ef6\u5c31\u7eea\u4e86epoll_wait\u51fd\u6570\u8fd4\u56de\u4e86\u5c31\u4e0d\u5728\u963b\u585e\u4e86\u3002\u4ee3\u7801\u5982\u4e0b&#xff1a;<\/p>\n<p>using Functor &#061; std::function&lt;void()&gt;;<\/p>\n<p>#include&lt;thread&gt;<br \/>\n#include&lt;mutex&gt;<br \/>\n#include&lt;memory&gt;<br \/>\n#include&lt;sys\/eventfd.h&gt;<br \/>\n\/\/\u4efb\u52a1\u6267\u884c\u7684Loop\u2014\u2014\u4e8b\u4ef6\u5faa\u73af\u6838\u5fc3\u662fReactor\u7684\u6838\u5fc3<br \/>\nclass EventLoop{<br \/>\n    private:<br \/>\n        std::thread::id _thread_id;\/\/\u7ebf\u7a0bID<\/p>\n<p>        int _event_fd;\/\/eventfd\u5524\u9192IO\u4e8b\u4ef6\u76d1\u63a7\u6709\u53ef\u80fd\u5bfc\u81f4\u7684\u963b\u585e,\u6765\u4e00\u4e2a\u4efb\u52a1\u8981\u538b\u5165\u961f\u5217\u90a3\u4e48\u5c31\u8981\u5524\u9192\u5728epoll_wait\u7684\u963b\u585e\u5c31\u8981\u7528\u5230\u8fd9\u4e2a\u95f9\u949ffd<br \/>\n        std::unique_ptr&lt;Channel&gt; _event_channel;<br \/>\n        \/\/\u5bf9\u6240\u6709\u7684\u8fde\u63a5\u7684\u4e8b\u4ef6\u505a\u7ba1\u7406&#xff0c;\u56e0\u4e3a\u7ebf\u7a0b\u6c60\u91c7\u7528RR\u8f6e\u8be2\u7684\u65b9\u5f0f&#xff0c;\u4e00\u4e2a\u7ebf\u7a0b\u4f1a\u7ba1\u7406\u591a\u4e2a\u8fde\u63a5<br \/>\n        Poller _poller;\/\/\u8fdb\u884c\u6240\u6709\u63cf\u8ff0\u7b26\u7684\u4e8b\u4ef6\u76d1\u63a7<\/p>\n<p>        std::vector&lt;Functor&gt; _tasks;\/\/\u4efb\u52a1\u6c60<br \/>\n        std::mutex _mutex;\/\/\u5b9e\u73b0\u4efb\u52a1\u6c60\u64cd\u4f5c\u7684\u7ebf\u7a0b\u5b89\u5168<br \/>\n        TimerWheel _timer_wheel;\/\/\u5b9a\u65f6\u5668\u6a21\u5757<br \/>\n    public:<br \/>\n        void RunAllTask(){<br \/>\n            std::vector&lt;Functor&gt; functor;<br \/>\n            {<br \/>\n                std::unique_lock&lt;std::mutex&gt; _lock(_mutex);<br \/>\n                _tasks.swap(functor);<br \/>\n            }<br \/>\n            for(auto&amp;f : functor)f();<br \/>\n            return ;<br \/>\n        }<br \/>\n        static int CreateEventFd(){<br \/>\n            int efd &#061; eventfd(0,EFD_CLOEXEC | EFD_NONBLOCK);<br \/>\n            if(efd&lt;0){<br \/>\n                ERR_LOG(&#034;eventfd failed!!!&#034;);<br \/>\n                abort();\/\/\u8ba9\u7a0b\u5e8f\u5f02\u5e38\u9000\u51fa<br \/>\n            }<br \/>\n            return efd;<br \/>\n        }<br \/>\n        void ReadEventFd(){<br \/>\n            uint64_t res &#061; 0;<br \/>\n            int ret &#061;read(_event_fd,&amp;res,sizeof(res));<br \/>\n            if(ret &lt;0){<br \/>\n                \/\/EAGAIN\u662f\u8d44\u6e90\u5360\u65f6\u4e0d\u53ef\u7528(\u6bd4\u5982\u8bfb\u5b8c\u4e86\u6570\u636e\/\u6ca1\u6570\u636e\u53ef\u8bfb)&#xff0c;EINTR\u662f\u7cfb\u7edf\u8c03\u7528\u56e0\u4fe1\u53f7\u4e2d\u65ad\u800c\u63d0\u524d\u7ec8\u6b62<br \/>\n                if(errno &#061;&#061; EINTR || errno &#061;&#061; EAGAIN){<br \/>\n                    return;<br \/>\n                }<br \/>\n                \/\/\u8fd9\u91cc\u5c31\u662f\u4e25\u91cd\u9519\u8bef<br \/>\n                ERR_LOG(&#034;read eventd \u5931\u8d25&#xff01;&#xff01;&#034;);<br \/>\n                abort();<br \/>\n            }<br \/>\n            return;<br \/>\n        }<br \/>\n        void WeakUpEventFd(){<br \/>\n            uint64_t val &#061;1;<br \/>\n            int ret &#061; write(_event_fd,&amp;val,sizeof(val));<br \/>\n            if(ret &lt;0){<br \/>\n                if(errno &#061;&#061; EINTR){<br \/>\n                    return;<br \/>\n                }<br \/>\n                \/\/\u8fd9\u91cc\u5c31\u662f\u4e25\u91cd\u9519\u8bef<br \/>\n                ERR_LOG(&#034;write eventd \u5931\u8d25&#xff01;&#xff01;&#034;);<br \/>\n                abort();<br \/>\n            }<br \/>\n            return;<br \/>\n        }<br \/>\n    public:<br \/>\n        EventLoop():_thread_id(std::this_thread::get_id()),<br \/>\n                    _event_fd(CreateEventFd()),<br \/>\n                    _event_channel(new Channel(this,_event_fd)),<br \/>\n                    _timer_wheel(this){<br \/>\n            \/\/\u7ed9eventfd\u6dfb\u52a0\u53ef\u8bfb\u4e8b\u4ef6\u56de\u8c03\u51fd\u6570&#xff0c;\u8bfb\u53d6eventfd\u4e8b\u4ef6\u901a\u77e5\u6b21\u6570<br \/>\n            _event_channel-&gt;SetReadCallback(std::bind(&amp;EventLoop::ReadEventFd,this));<br \/>\n            \/\/\u542f\u52a8eventfd\u7684\u8bfb\u4e8b\u4ef6\u76d1\u63a7<br \/>\n            _event_channel-&gt;EnableRead();<br \/>\n        }<br \/>\n        void Start(){<br \/>\n            \/\/\u8fd9\u4e2a\u5faa\u73af\u53ef\u4ee5\u52a0\u5230start\u91cc\u9762\u4e5f\u53ef\u4ee5\u5728\u5916\u90e8\u8c03\u7528start\u65f6\u5957\u4e0a\u4e00\u5c42\u5faa\u73af<br \/>\n            \/\/Reactor\u7684\u4f53\u73b0\u6240\u5728&#xff0c;Reactor\u5c31\u662f\u4e00\u79cd\u624b\u6bb5\u548c\u65b9\u6cd5\u2014\u2014\u76d1\u542c\u4e8b\u4ef6&#xff0c;\u7136\u540e\u5728\u76d1\u542c\u4e8b\u4ef6\u4e2d\u6267\u884c\u5bf9\u5e94\u53ef\u6267\u884c\u4e8b\u4ef6\u3002<br \/>\n            while(true){<br \/>\n                \/\/\u5206\u4e09\u6b65&#xff1a;1.\u4e8b\u4ef6\u76d1\u63a7 2.\u5c31\u7eea\u4e8b\u4ef6\u5904\u7406 3.\u6267\u884c\u4efb\u52a1<br \/>\n                \/\/1.\u4e8b\u4ef6\u76d1\u63a7<br \/>\n                std::vector&lt;Channel*&gt; actives;<br \/>\n                _poller.Poll(&amp;actives);<br \/>\n                \/\/\u8fd9\u91cc\u987a\u5e8f\u4e0d\u80fd\u53d8\u901a\u5e38IO\u662f\u5b9e\u65f6\u7684&#xff0c;\u5bf9\u5ef6\u8fdf\u654f\u611f&#xff0c;\u5e94\u8be5\u7acb\u5373\u5904\u7406\u3002<br \/>\n                \/\/\u5c31\u7eea\u4e8b\u4ef6\u7684\u5904\u7406<br \/>\n                for(auto &amp;channel:actives)channel-&gt;HandleEvent();<br \/>\n                \/\/\u6267\u884c\u4efb\u52a1\u2014\u2014\u628aclose(fd)\u5173\u95ed\u5ba2\u6237\u7aef\u8fde\u63a5\u653e\u5230\u4efb\u52a1\u6c60\u4e2d(\u907f\u514d\u6211\u8fd8\u5728\u5904\u7406\u6211\u5c31\u76f4\u63a5\u5173\u4e86)\u3001\u5b9a\u65f6\u5668\u4efb\u52a1<br \/>\n                RunAllTask();<br \/>\n            }<br \/>\n        }<\/p>\n<p>        \/\/\u7528\u4e8e\u5224\u65ad\u5f53\u524d\u7ebf\u7a0b\u662f\u5426\u662fEventLoop\u5bf9\u5e94\u7684\u7ebf\u7a0b<br \/>\n        bool IsInLoop(){<br \/>\n            return (_thread_id &#061;&#061; std::this_thread::get_id());<br \/>\n        }<\/p>\n<p>        \/\/\u786e\u4fdd\u51fd\u6570\u6267\u884c\u65f6loop\u4e2d\u6267\u884c\u7684<br \/>\n        void AssertInLoop(){<br \/>\n            assert(_thread_id &#061;&#061; std::this_thread::get_id());<br \/>\n        }<br \/>\n        \/\/\u5224\u65ad\u5c06\u8981\u6267\u884c\u7684\u4efb\u52a1\u662f\u5426\u5904\u4e8e\u5f53\u524d\u7ebf\u7a0b\u4e2d&#xff0c;\u5982\u679c\u662f\u5c31\u76f4\u63a5\u6267\u884c&#xff0c;\u5982\u679c\u4e0d\u662f\u5c31\u63d2\u5165\u4efb\u52a1\u961f\u5217\u4e2d\u3002<br \/>\n        \/\/\u8fd9\u4e3b\u8981\u662f\u4e3a\u4e86\u62d3\u5c55\u4e1a\u52a1\u573a\u666f&#xff0c;\u6bd4\u5982\u8fde\u63a5\u7ba1\u7406\u7ebf\u7a0b&#xff0c;\u534f\u8bae\u89e3\u6790\u7ebf\u7a0b&#xff0c;\u4e1a\u52a1\u903b\u8f91\u7ebf\u7a0b&#xff0c;\u6570\u636e\u5e93\u7ebf\u7a0b&#xff0c;\u54cd\u5e94\u7ec4\u88c5\u7ebf\u7a0b\u3002\u591a\u4e2a\u7ebf\u7a0b\u7684\u65f6\u5019\u6211\u4e00\u4e2a\u8fde\u63a5\u4e00\u4e2a\u5728\u4e3b\u7ebf\u7a0b\u4e2d\u6267\u884c\u4efb\u52a1&#xff0c;\u8fde\u63a5\u7ba1\u7406\u7ebf\u7a0b\u662f\u4e3b\u7ebf\u7a0b<br \/>\n        void RunInLoop(const Functor &amp; cb){<br \/>\n            if(IsInLoop()){<br \/>\n                return cb();<br \/>\n            }<br \/>\n            return QueueInLoop(cb);<br \/>\n        }<\/p>\n<p>        \/\/\u5c06\u64cd\u4f5c\u538b\u5165\u4efb\u52a1\u6c60<br \/>\n        void QueueInLoop(const Functor &amp;cb){<br \/>\n            {<br \/>\n                std::unique_lock&lt;std::mutex&gt; _lock(_mutex);<br \/>\n                _tasks.push_back(cb);<br \/>\n            }<br \/>\n            \/\/\u5524\u9192\u54ea\u4e9b\u56e0\u4e3a_poller.Poll()\u65f6\u7684\u963b\u585e\u7ebf\u7a0b&#xff0c;\u4e0d\u7136\u4efb\u52a1\u961f\u5217\u534a\u5929\u4e0d\u4f1a\u88ab\u6267\u884c<br \/>\n            WeakUpEventFd();<br \/>\n        }<\/p>\n<p>        \/\/\u6dfb\u52a0\/\u4fee\u6539\u63cf\u8ff0\u7b26\u7684\u4e8b\u4ef6\u76d1\u63a7<br \/>\n        void UpdateEvent(Channel* channel){<br \/>\n            return _poller.UpdateEvent(channel);<br \/>\n        }<\/p>\n<p>        \/\/\u79fb\u9664\u63cf\u8ff0\u7b26\u7684\u76d1\u63a7<br \/>\n        void RemoveEvent(Channel* channel){<br \/>\n            return _poller.RemoveEvent(channel);<br \/>\n        }<\/p>\n<p>        void TimerAdd(uint64_t id,uint32_t delay,const TaskFunc&amp; cb){<br \/>\n            return _timer_wheel.TimerAdd(id,delay,cb);<br \/>\n        }<br \/>\n        void TimerRefresh(uint64_t id){return _timer_wheel.TimerRefresh(id);}<br \/>\n        void TimerCancel(uint64_t id){return _timer_wheel.TimerCancel(id);}<br \/>\n        \/\/\u5982\u679c\u6211\u8981\u628a\u5b9a\u65f6\u5668\u505c\u4e86&#xff0c;\u7136\u540e\u518d\u542f\u7528\u90a3\u4e48\u5c31\u9700\u8981\u8fd9\u4e2a\u63a5\u53e3<br \/>\n        bool HashTimer(uint64_t id){return _timer_wheel.HashTimer(id);}<br \/>\n}; <\/p>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u5728\u6210\u5458\u53d8\u91cf\u4e2d\u6709&#xff0c;\u7ebf\u7a0bID\u3001event_fd(\u95f9\u949ffd)\u3001\u95f9\u949f\u7684Channel\u3001\u5bf9\u6240\u6709\u8fde\u63a5\u7684\u7ba1\u7406Poll\u7c7b\u3001\u4efb\u52a1\u6c60\u3001\u5b9a\u65f6\u5668\u3001\u9501\u3002\u5176\u4e2d\u7ebf\u7a0bID\u548cevent_fd\u662f\u4e3a\u4e86\u5728\u5355\u4e2a\u8fde\u63a5\u7684\u591a\u7ebf\u7a0b\u573a\u666f\u4e0b\u6240\u8bbe\u7f6e\u7684&#xff0c;\u7ebf\u7a0bID\u662f\u4e3a\u4e86\u7ebf\u7a0b\u5b89\u5168&#xff0c;\u4fdd\u8bc1\u5728\u591a\u7ebf\u7a0b\u573a\u666f\u4e2d\u6211\u538b\u5165\u5230\u4e00\u4e2a\u4efb\u52a1\u961f\u5217\u4e2d&#xff0c;\u4f9d\u6b21\u6267\u884c\u3002\u6700\u597d\u4f7f\u7528\u9501\u786e\u4fdd\u6570\u636e\u7684\u4e00\u81f4\u6027\u3002\u5728\u5355\u8fde\u63a5\u591a\u7ebf\u7a0b\u573a\u666f\u4e2d&#xff0c;\u6211\u53ef\u80fd\u6709\u5de5\u4f5c\u7ebf\u7a0b&#xff0c;\u6570\u636e\u5e93\u7ebf\u7a0b&#xff0c;\u4e1a\u52a1\u7ebf\u7a0b&#xff0c;\u94fe\u63a5\u7ba1\u7406\u7ebf\u7a0b&#xff0c;\u4e0d\u540c\u7ebf\u7a0b\u8981\u628a\u4efb\u52a1\u538b\u5165&#xff0c;\u540c\u65f6\u56e0\u4e3a\u6211\u7684EventLoop\u542f\u52a8\u540e\u4e00\u76f4\u5728Poll\u963b\u585e\u7b49\u5f85\u5c31\u7eea\u4e8b\u4ef6&#xff0c;\u6240\u4ee5\u8fd9\u91cc\u4e3a\u4e86\u9632\u6b62\u6211\u4e00\u76f4\u538b\u5165\u4efb\u52a1&#xff0c;\u4efb\u52a1\u786e\u4e0d\u80fd\u6267\u884c&#xff0c;\u6211\u5c31\u8bbe\u7f6eeventfd\u8fd9\u4e2a\u53d8\u91cf&#xff0c;\u5c31\u76f8\u5f53\u4e8e\u95f9\u949f&#xff0c;\u6211\u628a\u95f9\u949f\u6302\u5230epoll\u7684\u7ea2\u9ed1\u6811\u4e2d&#xff0c;\u538b\u5165\u4efb\u52a1\u540e\u6211\u5c31\u8c03\u7528WeakUpEventFd\u51fd\u6570\u5c31\u4f1a\u5199\u5165\u6570\u636e\u5230eventfd\u4e2d\u6fc0\u6d3bepoll_wait&#xff0c;\u5c31\u7eea\u4e8b\u4ef6\u89e6\u53d1\u5c31\u4e0d\u4f1a\u963b\u585e\u4e86&#xff0c;\u5c31\u4f9d\u6b21\u6267\u884c\u4efb\u52a1\u6c60\u4e2d\u7684\u4efb\u52a1<\/p>\n<h3>4.4 \u9ad8\u7ea7\u7279\u6027\u6a21\u5757<\/h3>\n<h4>4.4.1\u00a0TimerTask\u7c7b\u2014\u2014\u4efb\u52a1\u8d85\u65f6\u7c7b<\/h4>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u5b9a\u65f6\u4efb\u52a1\u6211\u8fd9\u91cc\u7684\u601d\u8def\u5c31\u662f\u5728\u6790\u6784\u51fd\u6570\u4e2d\u8c03\u81ea\u5df1\u7684_task_cb\u4efb\u52a1\u56de\u8c03&#xff0c;\u7136\u540e\u518d\u65f6\u95f4\u8f6e\u5b9a\u65f6\u5668\u91cc\u8d85\u65f6\u4e86\u5c31\u76f4\u63a5\u628a\u65f6\u95f4\u8f6e\u4e2d\u7684\u5b9a\u65f6\u4efb\u52a1clear()\u81ea\u52a8\u8c03\u7528\u81ea\u5df1\u7684\u6790\u6784\u51fd\u6570\u81ea\u52a8\u6267\u884c\u8d85\u65f6\u4efb\u52a1\u4e86\u3002\u5176\u4f59\u7684\u5c31\u662f\u6210\u5458\u53d8\u91cf\u7684\u8bbe\u7f6e\u3002<\/p>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u7528\u4e00\u4e2a64\u4f4d\u7684\u6574\u5f62\u505a\u5b9a\u65f6\u5668\u7684ID&#xff0c;2^64\u4e2a\u5b9a\u65f6\u5668\u9762\u5bf9&#xff0c;\u9ad8\u5e76\u53d1\u7684\u670d\u52a1\u5668\u4e5f\u9519\u9519\u6709\u4f59\u4e86&#xff0c;\u8d85\u65f6\u65f6\u95f4\u7528\u4e00\u4e2a32\u4f4d\u7684\u6574\u5f62\u5176\u5b9e16\u4f4d\u6574\u578b\u751a\u81f3uint_8\u90fd\u884c\u5177\u4f53\u770b\u5e94\u7528\u573a\u666f&#xff0c;\u7528_canceled\u6807\u8bb0\u8fd9\u4e2a\u4efb\u52a1\u662f\u5426\u88ab\u53d6\u6d88\u5b9a\u65f6\u4e86&#xff0c;\u907f\u514d\u91cd\u590d\u6267\u884c&#xff0c;\u7136\u540e\u5c31\u662f\u5b9a\u65f6\u4efb\u52a1\u51fd\u6570\u4ee5\u53ca_release\u51fd\u6570\u2014\u2014\u8fd9\u4e2a\u51fd\u6570\u662f\u4e3a\u4e86\u6211\u5728\u6267\u884c\u5b9a\u65f6\u4efb\u52a1\u7684\u65f6\u5019\u987a\u4fbf\u628a\u5b9a\u65f6\u4efb\u52a1\u5728\u65f6\u95f4\u8f6e\u7ba1\u7406\u7c7b\u4e2d\u7684\u4fdd\u5b58\u8bb0\u5f55\u4e5f\u5220\u4e86\u76ee\u7684\u5c31\u662f\u65b9\u4fbf\u4e5f\u7b26\u5408\u9ad8\u5185\u805a\u4f4e\u5076\u5c14\u539f\u5219\u3002\u4ee3\u7801\u5982\u4e0b&#xff1a;<\/p>\n<p>using TaskFunc &#061; std::function&lt;void()&gt;;<br \/>\nusing ReleaseFunc &#061; std::function&lt;void()&gt;;<\/p>\n<p>\/\/\u5355\u4e2a\u8d85\u65f6\u4efb\u52a1\u7c7b\u2014\u2014\u4e3b\u8981\u662f\u8d85\u65f6\u4e86\u5c31\u5728\u4ed6\u7684\u6790\u6784\u51fd\u6570\u4e2d\u6267\u884c\u5b9a\u65f6\u4efb\u52a1<br \/>\nclass TimerTask{<br \/>\n    private:<br \/>\n        uint64_t _id;   \/\/\u5b9a\u65f6\u5668\u4efb\u52a1\u5bf9\u8c61ID<br \/>\n        uint32_t _timeout;\/\/\u5b9a\u65f6\u4efb\u52a1\u7684\u8d85\u65f6\u65f6\u95f4<br \/>\n        bool _canceled;\/\/ false-\u8868\u793a\u6ca1\u6709\u88ab\u53d6\u6d88&#xff0c; true-\u8868\u793a\u88ab\u53d6\u6d88<br \/>\n        TaskFunc _task_cb;\/\/\u5b9a\u65f6\u5668\u5bf9\u8c61\u8981\u6267\u884c\u7684\u5b9a\u65f6\u4efb\u52a1<br \/>\n        ReleaseFunc _release;\/\/\u7528\u4e8e\u5220\u9664TimerWheel\u4e2d\u4fdd\u5b58\u7684\u5b9a\u65f6\u5668\u5bf9\u8c61\u4fe1\u606f<br \/>\n    public:<br \/>\n        TimerTask(uint64_t id, uint32_t delay, const TaskFunc &amp;cb):<br \/>\n            _id(id), _timeout(delay), _task_cb(cb), _canceled(false) {}<br \/>\n        ~TimerTask()<br \/>\n        {<br \/>\n            if (_canceled &#061;&#061; false) _task_cb();<br \/>\n            _release();<br \/>\n        }<br \/>\n        void Cancel() { _canceled &#061; true; }<br \/>\n        void SetRelease(const ReleaseFunc &amp;cb) { _release &#061; cb; }<br \/>\n        uint32_t DelayTime() { return _timeout; }<br \/>\n}; <\/p>\n<h4>4.4.2\u00a0TimerWheel\u7c7b\u2014\u2014\u65f6\u95f4\u8f6e\u5b9a\u65f6\u5668<\/h4>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u4e0a\u9762\u8bf4\u4e86\u8d85\u65f6\u4efb\u52a1\u7c7b&#xff0c;\u8fd9\u91cc\u7684TImerWheel\u7c7b\u5c31\u662f\u6a21\u62df\u6307\u9488\u8df3\u52a8\u6765\u6267\u884c\u4efb\u52a1&#xff0c;\u5df2\u7ecf\u5bf9\u4efb\u52a1\u7684\u589e\u5220\u67e5\u6539\u7684\u3002\u4ee3\u7801\u5982\u4e0b&#xff1a;<\/p>\n<p>\/\/\u65f6\u95f4\u8f6e\u2014\u2014\u6a21\u62df\u65f6\/\u79d2\/\u5206\u949f\u7684\u8df3\u52a8\u2014\u2014\u8fd9\u91cc\u662f\u6a21\u62df\u79d2\u949f\u7684\u8df3\u52a8\u3002<br \/>\nclass TimerWheel{<br \/>\n    private:<br \/>\n        using WeakPtr &#061; std::weak_ptr&lt;TimerTask&gt;;<br \/>\n        using PtrTask &#061; std::shared_ptr&lt;TimerTask&gt;;<br \/>\n        int _tick;\/\/\u79d2\u9488\u7684\u4f4d\u7f6e<br \/>\n        int _capacity;\/\/\u8868\u76d8\u7684\u523b\u5ea6<br \/>\n        \/\/\u540c\u7406\u8fd9\u662fshared_ptr\u8868\u53ea\u5b58\u5728\u4e00\u4efd&#xff0c;clear\u4e86&#xff0c;\u5c31\u76f4\u63a5\u6790\u6784&#xff0c;\u56e0\u4e3a\u53ef\u80fd\u6709\u591a\u4e2a\u4efb\u52a1\u5728\u540c\u4e00\u4e2a\u65f6\u523b\u6240\u4ee5\u7528vector&lt;vector&lt;PtrTask&gt;&gt;\u7684\u5f62\u5f0f<br \/>\n        std::vector&lt;std::vector&lt;PtrTask&gt;&gt; _wheel;<br \/>\n        \/\/\u8fd9\u91cc\u5f88\u5173\u952e&#xff0c;\u6211\u627e\u4efb\u52a1\u7684\u8868\u53ea\u80fd\u5b58weak_ptr\u4e0d\u7136\u6211\u65e0\u6cd5\u505a\u5230\u6790\u6784\u51fd\u6570\u6267\u884c\u4efb\u52a1&#xff0c;\u56e0\u4e3a\u4efb\u52a1\u8868\u5b58shared_ptr\u7684\u8bdd\u90a3\u4e48\u5c31\u6c38\u8fdc\u6709\u4e00\u4e2a\u5b9e\u4f8b\u5728\u3002<br \/>\n        std::unordered_map&lt;uint64_t,WeakPtr&gt; _timers;<\/p>\n<p>        \/\/\u4e0b\u9762\u662f\u4e3a\u4e86\u628a\u5b9a\u65f6\u5668\u878d\u5408\u5230EventLoop\u4e2d\u6240\u9700\u8981\u6dfb\u52a0\u7684\u6210\u5458<br \/>\n        EventLoop* _loop;<br \/>\n        int _timerfd;\/\/\u5b9a\u65f6\u5668\u63cf\u8ff0\u7b26&#8211;\u53ef\u8bfb\u4e8b\u4ef6\u56de\u8c03\u5c31\u662f\u8bfb\u53d6\u8ba1\u6570\u5668&#xff0c;\u6267\u884c\u5b9a\u65f6\u4efb\u52a1<br \/>\n        std::unique_ptr&lt;Channel&gt; _timer_channel;<br \/>\n    private:<br \/>\n        void RemoveTimer(uint64_t id){<br \/>\n            auto it &#061; _timers.find(id);<br \/>\n            if(it&#061;&#061;_timers.end())return;<br \/>\n            _timers.erase(it);<br \/>\n        }<br \/>\n        static int CreateTimerfd(){<br \/>\n            int timerfd &#061; timerfd_create(CLOCK_MONOTONIC,0);<br \/>\n            if(timerfd &lt; 0){<br \/>\n                ERR_LOG(&#034;TIMERFD CREATE FAILED!!!&#034;);<br \/>\n                abort();<br \/>\n            }<br \/>\n            \/\/int timerfd_settime(int fd,int flags,struct itimerspc* new,struct itimerspc* old);<br \/>\n            struct itimerspec itime;<br \/>\n            itime.it_value.tv_sec&#061;1;<br \/>\n            itime.it_value.tv_nsec&#061;0;\/\/\u7b2c\u4e00\u6b21\u8d85\u65f6\u95f4\u4e3a1s\u540e<br \/>\n            itime.it_interval.tv_sec &#061;1;<br \/>\n            itime.it_interval.tv_nsec&#061;0;\/\/\u7b2c\u4e00\u6b21\u8d85\u65f6\u540e&#xff0c;\u6bcf\u6b21\u8d85\u65f6\u7684\u95f4\u9694\u65f6\u95f4<br \/>\n            timerfd_settime(timerfd,0,&amp;itime,nullptr);<br \/>\n            return timerfd;<br \/>\n        }<br \/>\n        int ReadTimefd(){<br \/>\n            uint64_t times;<br \/>\n            int ret &#061; read(_timerfd,&amp;times,8);<br \/>\n            if(ret&lt;0){<br \/>\n                ERR_LOG(&#034;READ TIMEFD FAILED!!!&#034;);<br \/>\n                abort();<br \/>\n            }<br \/>\n            return times;<br \/>\n        }<\/p>\n<p>        void RunTimerTask() {<br \/>\n            _tick &#061; (_tick &#043; 1) % _capacity;<br \/>\n            _wheel[_tick].clear();\/\/\u6e05\u7a7a\u6307\u5b9a\u4f4d\u7f6e\u7684\u6570\u7ec4&#xff0c;\u5c31\u4f1a\u628a\u6570\u7ec4\u4e2d\u4fdd\u5b58\u7684\u6240\u6709\u7ba1\u7406\u5b9a\u65f6\u5668\u5bf9\u8c61\u7684shared_ptr\u91ca\u653e\u6389<br \/>\n        }<br \/>\n        void OnTime(){<br \/>\n            int times &#061; ReadTimefd();<br \/>\n            for (int i &#061; 0; i &lt; times; i&#043;&#043;) {<br \/>\n                RunTimerTask();<br \/>\n            }<br \/>\n        }<br \/>\n        \/\/\u6dfb\u52a0\u5b9a\u65f6\u4efb\u52a1<br \/>\n        void TimerAddInLoop(uint64_t id , uint32_t delay,const TaskFunc&amp;cb){<br \/>\n            \/\/\u53ef\u80fd\u51fa\u73b0\u540c\u65f6\u63d2\u5165\u540c\u4e00\u4e2a\u4efb\u52a1\u7684\u60c5\u51b5<br \/>\n            \/\/\u65b0\u589e&#xff1a;\u68c0\u67e5ID\u662f\u5426\u5df2\u5b58\u5728&#xff0c;\u5b58\u5728\u5219\u5148\u53d6\u6d88\u65e7\u4efb\u52a1<br \/>\n            auto it &#061; _timers.find(id);<br \/>\n            if(it !&#061; _timers.end()){<br \/>\n                PtrTask old_task &#061; it-&gt;second.lock();<br \/>\n                if(old_task) old_task-&gt;Cancel(); \/\/ \u6807\u8bb0\u65e7\u4efb\u52a1\u53d6\u6d88&#xff0c;\u907f\u514d\u6267\u884c<br \/>\n            }<br \/>\n            PtrTask pt(new TimerTask(id,delay,cb));<br \/>\n            pt-&gt;SetRelease(std::bind(&amp;TimerWheel::RemoveTimer,this,id));<br \/>\n            int pos &#061; (_tick&#043;delay)%_capacity;<br \/>\n            _wheel[pos].push_back(pt);<br \/>\n            _timers[id]&#061;WeakPtr(pt);<br \/>\n        }<br \/>\n        \/\/\u5237\u65b0\/\u5ef6\u8fdf\u5b9a\u65f6\u4efb\u52a1<br \/>\n        void TimerRefreshInLoop(uint64_t id){<br \/>\n            \/\/\u901a\u8fc7\u4fdd\u5b58\u7684\u5b9a\u65f6\u5668\u5bf9\u8c61\u7684weak_ptr\u6784\u9020\u5904\u4e00\u4e2ashared_ptr\u51fa\u6765&#xff0c;\u6dfb\u52a0\u5230\u8f6e\u5b50\u4e2d<br \/>\n            auto it &#061; _timers.find(id);<br \/>\n            if(it &#061;&#061; _timers.end())return;<br \/>\n            PtrTask pt &#061; it-&gt;second.lock();\/\/lock\u83b7\u53d6weak_ptr\u7684\u5bf9\u8c61&#xff0c;\u5e76\u8d4b\u503c\u7ed9\u65b0\u7684shared_ptr\u53bb\u7ba1\u7406\u6b64\u65f6\u5f15\u7528\u8ba1\u6570&#043;1<br \/>\n            int delay &#061; pt-&gt;DelayTime();<br \/>\n            int pos &#061; (_tick&#043;delay)%_capacity;<br \/>\n            _wheel[pos].push_back(pt);<br \/>\n        }<br \/>\n        void TimerCancelInLoop(uint64_t id){<br \/>\n            auto it &#061; _timers.find(id);<br \/>\n            if(it &#061;&#061; _timers.end()){<br \/>\n                return;\/\/\u6ca1\u627e\u5230\u5b9a\u65f6\u4efb\u52a1&#xff0c;\u6ca1\u6cd5\u5237\u65b0&#xff0c;\u6ca1\u6cd5\u5ef6\u8fdf<br \/>\n            }<br \/>\n            PtrTask pt &#061; it-&gt;second.lock();<br \/>\n            if(pt)pt-&gt;Cancel();<br \/>\n        }<br \/>\n    public:<br \/>\n        TimerWheel(EventLoop* loop):_capacity(60),_tick(0),_wheel(_capacity),_loop(loop),<br \/>\n                                    _timerfd(CreateTimerfd()),_timer_channel(new Channel(_loop,_timerfd))<br \/>\n        {<br \/>\n            _timer_channel-&gt;SetReadCallback(std::bind(&amp;TimerWheel::OnTime,this));<br \/>\n            _timer_channel-&gt;EnableRead();\/\/\u542f\u52a8\u8bfb\u4e8b\u4ef6\u76d1\u63a7<br \/>\n        }<br \/>\n        void TimerAdd(uint64_t id , uint32_t delay,const TaskFunc&amp;cb);<br \/>\n        void TimerRefresh(uint64_t id);<br \/>\n        void TimerCancel(uint64_t id);<br \/>\n        \/\/\u8fd9\u4e2a\u63a5\u53e3\u5b58\u5728\u7ebf\u7a0b\u5b89\u5168\u95ee\u9898&#xff0c;\u4e0d\u80fd\u5728\u5176\u4ed6\u7ebf\u7a0b\u8c03\u7528\u53ea\u80fd\u5728\u5bf9\u5e94EventLoop\u4e2d\u8c03\u7528\u3002<br \/>\n        bool HashTimer(uint64_t id){<br \/>\n            auto it &#061; _timers.find(id);<br \/>\n            if(it &#061;&#061; _timers.end())return false;<br \/>\n            return true;<br \/>\n        }<\/p>\n<p>};<\/p>\n<h4>4.4.3 LoopThread\/LoopThreadPoll\u7c7b\u2014\u2014\u591a\u7ebf\u7a0b\u7c7b<\/h4>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u5728LoopThread\u7c7b\u4e2d\u6211\u4e0d\u80fd\u76f4\u63a5\u521b\u5efaEventLoop\u5b9e\u4f8b\u5bf9\u8c61\u4e0d\u7136\u7ebf\u7a0bID\u5c31\u662f\u4e3b\u7ebf\u7a0b\u7684ID\/\u5f53\u524d\u7ebf\u7a0bID&#xff0c;\u6240\u4ee5\u5728LoopThread\u4e2d\u662fEventLoop\u7684\u6307\u9488\u5bf9\u8c61&#xff0c;\u63a5\u7740\u6709\u4e00\u4e2a\u51fd\u6570ThreadEntry\u8fd9\u4e2a\u51fd\u6570\u662f\u4f20\u7ed9thread\u7684\u6267\u884c\u51fd\u6570&#xff0c;\u7136\u540e\u518dthread\u7ebf\u7a0b\u4e2d\u521b\u5efaloop&#xff0c;\u8fd9\u6837\u5728\u54ea\u4e2a\u7ebf\u7a0b\u4e2d\u521b\u5efa\u7684EventLoop\u4e2d\u7684\u7ebf\u7a0bid\u5c31\u662f\u54ea\u4e2a\u7ebf\u7a0b\u7684\u3002\u6211\u521b\u5efa\u4e86EventLoop\u5b9e\u4f8b\u540c\u65f6\u662f\u8981\u63d0\u4f9b\u7ed9\u5916\u90e8\u4f7f\u7528\u7684&#xff0c;\u6240\u4ee5\u6211\u8fd8\u9700\u8981\u4e00\u4e2aGetLoop\u51fd\u6570&#xff0c;\u4f46\u662f\u6211\u4e0d\u80fd\u6ca1\u6709\u521b\u5efa\u7ebf\u7a0b\u6211\u5c31\u76f4\u63a5\u7ed9\u522b\u4eba\u83b7\u53d6\u5427&#xff0c;\u8fd9\u6837\u662f\u9519\u8bef\u7684&#xff0c;\u6240\u4ee5\u8fd9\u91cc\u6211\u8fd8\u9700\u8981\u52a0\u4e0a\u6761\u4ef6\u53d8\u91cf\u53bb\u63a7\u5236\u987a\u5e8f&#xff0c;\u53ea\u6709\u521b\u5efa\u4e86\u7ebf\u7a0b\u540e\u624d\u80fd\u53bb\u8c03\u7528GetLoop\u51fd\u6570\u53bb\u83b7\u53d6EventLoop\u5b9e\u4f8b\u3002\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/p>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u5728LoopThreadPoll\u7c7b\u4e2d\u91c7\u7528RR\u8f6e\u8be2\u7684\u65b9\u5f0f\u53bb\u4e00\u6b21\u8bbf\u95ee\u7ebf\u7a0b\u6c60\u4e2d\u7684\u5176\u4f59\u7ebf\u7a0b\u3002\u7528vector&lt;LoopThread*&gt; _threads\u4fdd\u5b58\u6240\u6709\u7684LoopThread\u5bf9\u8c61(\u7ebf\u7a0b\u6c60)&#xff0c;\u7528vector&lt;EventLoop*&gt; _loops\u4fdd\u5b58\u7ebf\u7a0b\u6c60\u4e2d\u7684EventLoop\u5bf9\u8c61&#xff0c;\u8fd9\u91cc\u4e0b\u6807\u662f\u5bf9\u5e94\u5173\u7cfb&#xff0c;\u7ebf\u7a0b\u7684\u4e0b\u6807\u548cEventLoop\u7684\u4e0b\u6807\u662f\u4e00\u6837\u7684\u3002_threads\u548c_loops\u7684\u5927\u5c0f\u5c31\u662f\u7ebf\u7a0b\u6c60\u5927\u5c0f\u7528_thread_count\u6765\u8bbe\u7f6e&#xff0c;\u7528_next_idx\u8868\u793a\u5e94\u8be5\u5de5\u4f5c\u5230\u54ea\u4e00\u4e2a\u7ebf\u7a0b\u4e86\u56e0\u4e3a\u662fRR\u8f6e\u8be2\u7684\u65b9\u5f0f\u3002<\/p>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u4ee3\u7801\u5982\u4e0b&#xff1a;<\/p>\n<p>\/\/\u5148\u6709\u7ebf\u7a0b\u518d\u6709EventLoop\u5bf9\u8c61&#xff0c;\u7136\u540eEventLoop\u5bf9\u8c61\u5728\u7ebf\u7a0b\u4e2d\u5b9e\u4f8b\u5316(\u4e0d\u7136\u8bbe\u7f6eid\u5c31\u662f\u4e3b\u7ebf\u7a0b\u7684\u7ebf\u7a0bid)&#xff0c;\u8fd9\u6837\u624d\u80fd\u4fdd\u8bc1id\u662f\u552f\u4e00\u7684&#xff0c;<br \/>\n#include &lt;condition_variable&gt; \/\/ \u6761\u4ef6\u53d8\u91cf\u7684\u6838\u5fc3\u5934\u6587\u4ef6<br \/>\n#include &lt;mutex&gt;              \/\/ \u5404\u79cd\u9501&#xff08;\u4e92\u65a5\u9501\u3001\u9012\u5f52\u9501\u7b49&#xff09;\u7684\u6838\u5fc3\u5934\u6587\u4ef6<br \/>\nclass LoopThread{<br \/>\n    private:<br \/>\n        \/\/\u540c\u6b65\u64cd\u4f5c<br \/>\n        std::mutex _mutex;\/\/\u4e92\u65a5\u9501<br \/>\n        std::condition_variable _cond;\/\/\u6761\u4ef6\u53d8\u91cf<\/p>\n<p>        \/\/\u521b\u5efa\u4e00\u4e2a\u7ebf\u7a0b\u4e00\u4e2aEventLoop\u7684\u5b9e\u4f8b\u5316<br \/>\n        EventLoop *_loop;   \/\/EventLoop\u7684\u6307\u9488\u53d8\u91cf&#xff0c;\u8fd9\u4e2a\u5bf9\u8c61\u9700\u8981\u5728\u7ebf\u7a0b\u5185\u53d6\u5b9e\u4f8b\u5316&#xff0c;\u6240\u4ee5\u8981\u521d\u59cb\u5316\u4e3a\u6307\u9488(\u5f15\u7528\u521d\u59cb\u5316\u5fc5\u987b\u8d4b\u503c&#xff0c;\u6240\u4ee5\u8fd9\u91cc\u8fd8\u662f\u7528\u6307\u9488)&#xff0c;\u4f20\u9012\u6211\u7684loop\u5bf9\u8c61\u7ed9\u4e3b\u7ebf\u7a0b<br \/>\n        std::thread _thread;\/\/EventLoop\u5bf9\u5e94\u7684\u7ebf\u7a0b<br \/>\n    private:<br \/>\n        \/\/\u5b9e\u4f8b\u5316EventLoop\u5bf9\u8c61&#xff0c;\u5524\u9192_cond\u4e0a\u53ef\u80fduse\u7684\u7ebf\u7a0b&#xff0c;\u5e76\u4e14\u5f00\u59cb\u8fd0\u884cEventLoop\u6a21\u5757\u7684\u529f\u80fd\u2014\u2014\u5b9e\u9645\u4e0a\u5c31\u662f\u53bb\u8fd0\u884cstart\u51fd\u6570<br \/>\n        void ThreadEntry(){<br \/>\n            \/\/\u4f46\u662f\u6ce8\u610f\u8fd9\u662f\u5c40\u90e8\u53d8\u91cf\u51fd\u6570\u9000\u51fa\u5c31\u9500\u6bc1\u4e86&#xff0c;\u6240\u4ee5\u4e0b\u9762\u7684start\u662f\u5faa\u73af\u6267\u884c\u7684<br \/>\n            EventLoop loop;\/\/\u8fd9\u91cc\u4e3a\u4ec0\u4e48\u4e0d\u76f4\u63a5\u4f7f\u7528_loop\u5462&#xff1f;\u2014\u2014\u9996\u5148\u662f\u5c40\u90e8\u7684&#xff0c;\u6240\u4ee5\u8df3\u51fa\u4f5c\u7528\u57df\u81ea\u52a8\u9500\u6bc1\u4e86&#xff0c;\u5176\u6b21\u8fd9\u662f\u4e00\u4e2aEventLoop\u5b9e\u4f8b&#xff0c;\u76f4\u63a5\u8d4b\u503c\u4e86\u3002\u5982\u679cLoopThread\u4e2d_loop\u662f\u5b9e\u4f8b\u5bf9\u8c61\u7684\u8bdd&#xff0c;\u90a3\u4e48\u7ebf\u7a0bid\u5c31\u662f\u4e3b\u7ebf\u7a0b\u4e5f\u5c31\u662f\u521b\u5efa\u5b9e\u4f8b\u7684\u7ebf\u7a0bid\u4e86&#xff0c;\u6211\u628a\u8fd9\u4e2a\u5f53\u4f5cthread()\u51fd\u6570\u7684\u51fd\u6570\u4f20\u5165thread\u7136\u540e\u5728\u65b0\u7684\u7ebf\u7a0b\u4e2d\u521b\u5efa&#xff0c;\u8fd9\u6837id\u5c31\u662f\u65b0\u7ebf\u7a0b\u7684id\u4e86<br \/>\n            {<br \/>\n                std::unique_lock&lt;std::mutex&gt; lock(_mutex);\/\/\u52a0\u9501<br \/>\n                _loop&#061;&amp;loop;<br \/>\n                _cond.notify_all();\/\/\u5524\u9192\u6240\u6709\u7b49\u5f85\u7684\u6761\u4ef6\u53d8\u91cf<br \/>\n            }<br \/>\n            loop.Start();<br \/>\n        }<br \/>\n        public:<br \/>\n        \/\/\u5728\u6784\u9020\u51fd\u6570\u4e2d\u521b\u5efa\u7ebf\u7a0b&#xff0c;\u8bbe\u5b9a\u7ebf\u7a0b\u7684\u5165\u53e3\u51fd\u6570\u2014\u2014\u8c03\u7528\u6784\u9020\u51fd\u6570\u5c31\u81ea\u52a8\u521b\u5efa\u7ebf\u7a0b<br \/>\n        LoopThread():_loop(nullptr),_thread(std::thread(std::bind(&amp;LoopThread::ThreadEntry,this))){}<br \/>\n        \/\/\u5f53\u5916\u754c\u6709\u4e00\u4e2a\u65b0\u94fe\u63a5\u6765\u4e86&#xff0c;\u6211\u5f97\u83b7\u53d6\u8fd9\u4e2aEventLoop\u624d\u80fd\u53bb\u6dfb\u52a0\u4efb\u52a1&#xff0c;\u624d\u80fd\u5c06EventLoop\u548c\u8fde\u63a5\u5173\u8054<br \/>\n        \/\/\u4f46\u662f\u6211\u4eec\u8981\u6ce8\u610f&#xff0c;\u5047\u8bbe\u6b64\u65f6\u6211\u4eec\u8fd8\u6ca1\u6709\u8bbe\u7f6eEventLoop&#xff0c;\u5c31\u574f\u4e8b\u4e86\u6240\u4ee5\u6b64\u65f6\u8981\u7528\u6761\u4ef6\u53d8\u91cf\u6765\u63a7\u5236\u987a\u5e8f&#xff0c;GetLoop\u4e2d\u5c31\u963b\u585e\u7b49\u5f85\u5b9e\u4f8b\u5316\u5b8c\u4e86\u624d\u53ef\u4ee5\u83b7\u53d6EventLoop\u5b9e\u4f8b\u5316\u5bf9\u8c61<br \/>\n        EventLoop *GetLoop(){<br \/>\n            EventLoop *loop &#061; nullptr;<br \/>\n            {<br \/>\n                std::unique_lock&lt;std::mutex&gt; lock(_mutex);\/\/\u52a0\u9501-\u5728\u6784\u9020\u51fd\u6570\u4e2d\u7b49\u5f85<br \/>\n                \/\/\u4f7f\u7528&amp;\u2014\u2014\u907f\u514d\u62f7\u8d1d&#xff0c;\u5f15\u7528\u7684\u65b9\u5f0f\u83b7\u53d6\u5916\u90e8\u6240\u6709\u7684\u53d8\u91cf&#xff0c;\u53ef\u4fee\u6539\u3002&#061;\u4e0d\u53ef\u4fee\u6539&#xff0c;\u8fd8\u4f1a\u9020\u6210\u62f7\u8d1d<br \/>\n                _cond.wait(lock,[&amp;](){return _loop !&#061;nullptr;});\/\/loop\u4e3anullptr\u5c31\u963b\u585e&#xff0c;\u7b49\u5f85\u88ab\u5524\u9192&#xff0c;\u628a\u5224\u65ad\u6761\u4ef6\u5199\u5230wait\u51fd\u6570\u4e2d<br \/>\n                loop&#061;_loop;<br \/>\n            }<br \/>\n            return loop;<br \/>\n        }<\/p>\n<p>};<\/p>\n<p>\/\/\u7ebf\u7a0b\u6c60<br \/>\nclass LoopThreadPoll{<br \/>\n    private:<br \/>\n        int _thread_count;\/\/\u4ece\u5c5e\u7ebf\u7a0b\u7684\u6570\u91cf<br \/>\n        int _next_idx;\/\/\u5f53\u524d\u54ea\u4e00\u4e2a\u7ebf\u7a0b\u5728\u8fd0\u884c\/\u5de5\u4f5c\u5230\u54ea\u4e00\u4e2a\u7ebf\u7a0b\u4e86<br \/>\n        EventLoop* _baseloop;\/\/\u4e3bEventLoop&#xff0c;\u8fd0\u884c\u5728\u4e3b\u7ebf\u7a0b&#xff0c;\u4ece\u5c5e\u7ebf\u7a0b\u6570\u91cf\u4e3a0&#xff0c;\u5219\u6240\u6709\u64cd\u4f5c\u90fd\u5728baseloop\u4e2d\u8fdb\u884c<br \/>\n        std::vector&lt;LoopThread*&gt; _threads;\/\/\u4fdd\u5b58\u6240\u6709\u7684LoopThread\u5bf9\u8c61<br \/>\n        std::vector&lt;EventLoop*&gt; _loops;\/\/\u4ece\u5c5e\u7ebf\u7a0b\u6570\u91cf\u5927\u4e8e0\u5219\u4ece_loops\u4e2d\u8fdb\u884c\u7ebf\u7a0bEventLoop\u5206\u914d\u2014\u2014\u8bbe\u7f6e\u8fd9\u4e2avector\u662f\u6709\u5fc5\u8981\u7684&#xff0c;\u56e0\u4e3a\u6211\u4e0d\u80fd\u76f4\u63a5\u4f7f\u7528_threads-&gt;_loop\u5bf9\u8c61&#xff0c;\u56e0\u4e3a\u6b64\u65f6_loop\u53ef\u80fd\u662f\u975e\u7ebf\u7a0b\u5b89\u5168\u7684&#xff0c;\u53ef\u80fd\u6ca1\u6709\u521b\u5efa&#xff0c;\u7528GetLoop\u51fd\u6570\u80af\u5b9a\u662f\u5b58\u5728\u624d\u80fd\u83b7\u53d6\u7684\u3002\u6240\u4ee5\u4e3a\u4e86\u65b9\u4fbf\u7528\u6570\u7ec4\u5b58EventLoop\u5bf9\u8c61<br \/>\n    public:<br \/>\n        LoopThreadPoll(EventLoop *baseloop):_thread_count(0),_next_idx(0),_baseloop(baseloop){}<br \/>\n        \/\/\u8bbe\u7f6e\u7ebf\u7a0b\u6570\u91cf<br \/>\n        void SetThreadCount(const int count){_thread_count&#061;count;}<br \/>\n        \/\/\u521b\u5efa\u6240\u6709\u7684\u4ece\u5c5e\u7ebf\u7a0b<br \/>\n        void Create(){<br \/>\n            if(_thread_count&gt;0){<br \/>\n                _threads.resize(_thread_count);<br \/>\n                _loops.resize(_thread_count);<br \/>\n                for(int i&#061;0;i&lt;_thread_count;&#043;&#043;i){<br \/>\n                    _threads[i]&#061;new LoopThread();<br \/>\n                    _loops[i]&#061;_threads[i]-&gt;GetLoop();<br \/>\n                }<br \/>\n            }<br \/>\n        }<br \/>\n        \/\/\u56e0\u4e3a\u91c7\u53d6RR\u8f6e\u8be2\u7684\u65b9\u5f0f\u6240\u4ee5\u547d\u540d\u662f\u8fd4\u56de\u4e0b\u4e00\u4e2a\u7ebf\u7a0b<br \/>\n        EventLoop* NextLoop(){<br \/>\n            if(_thread_count&#061;&#061;0)return _baseloop;<br \/>\n            _next_idx&#061;(_next_idx&#043;1)%_thread_count;<br \/>\n            return _loops[_next_idx];<br \/>\n        }<br \/>\n}; <\/p>\n<h3>4.5 \u4e1a\u52a1\u6838\u5fc3\u6a21\u5757<\/h3>\n<h4>4.5.1 Acceptor\u7c7b\u2014\u2014\u76d1\u542c\u5957\u63a5\u5b57\u7ba1\u7406\u7c7b<\/h4>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u662f\u4e3bReactor\u7684\u5177\u4f53\u5b9e\u73b0\u7c7b&#xff0c;\u4e3bReactor\u7684\u4f5c\u7528\u5c31\u662f\u7ba1\u7406\u76d1\u542cfd&#xff0c;\u6765\u4e00\u4e2a\u8fde\u63a5\u5c31\u8c03\u7528\u56de\u8c03\u51fd\u6570\u53bb\u5efa\u7acb\u4e00\u4e2a\u8fde\u63a5\u7c7b&#xff0c;\u5e95\u5c42\u8fd8\u662f\u8c03\u7528\u4e86\u6211\u4eec\u4e4b\u524d\u5c01\u88c5\u7684Channel\u7c7b\u3001Socket\u7c7b\u3001EventLoop\u7c7b\u3002\u8fd9\u91cc\u7684EventLoop\u6211\u4eec\u76f4\u63a5\u4f7f\u7528\u4e3b\u7ebf\u7a0b\u7684EventLoop\u5c31\u884c\u4e86&#xff0c;\u4e5f\u5c31\u662fTcpServer\u7c7b\u7684EventLoop\u3002\u4ee3\u7801\u5982\u4e0b&#xff1a;<\/p>\n<p>class Acceptor{<br \/>\n    private:<br \/>\n        Socket _socket;\/\/\u7528\u4e8e\u521b\u5efa\u5957\u63a5\u5b57<br \/>\n        EventLoop *_loop;\/\/\u7528\u4e8e\u5bf9\u76d1\u542c\u5957\u63a5\u5b57\u8fdb\u884c\u4e8b\u4ef6\u76d1\u63a7<br \/>\n        Channel _channel;\/\/\u7528\u4e8e\u5bf9\u76d1\u542c\u5957\u63a5\u5b57\u8fdb\u884c\u4e8b\u4ef6\u76d1\u63a7<\/p>\n<p>        using AcceptCallback &#061; std::function&lt;void(int)&gt;;<br \/>\n        AcceptCallback _accept_callback;<br \/>\n    private:<br \/>\n        \/\/\u76d1\u542c\u5957\u63a5\u5b57\u7684\u8bfb\u4e8b\u4ef6\u56de\u8c03\u5904\u7406\u51fd\u6570&#8211;\u83b7\u53d6\u65b0\u8fde\u63a5&#xff0c;\u8c03\u7528_accept_callback\u51fd\u6570\u8fdb\u884c\u65b0\u94fe\u63a5\u5904\u7406<br \/>\n        void HandleRead(){<br \/>\n            int newfd &#061; _socket.Accept();<br \/>\n            if(newfd&lt;0)return;<br \/>\n            if(_accept_callback)_accept_callback(newfd);<br \/>\n        }<br \/>\n        int CreateServer(uint16_t port){<br \/>\n            bool ret &#061; _socket.CreateServer(port);<br \/>\n            assert(ret &#061;&#061; true);<br \/>\n            return _socket.Fd();<br \/>\n        }<br \/>\n    public:<\/p>\n<p>    \/\/\u8fd9\u91cc\u542f\u52a8\u4e8b\u4ef6\u76d1\u63a7\u6bd4\u8bbe\u7f6e\u56de\u8c03\u65e9&#xff0c;\u8fd9\u5c31\u4f1a\u5bfc\u81f4&#xff0c;\u7acb\u5373\u6709\u76d1\u63a7\u4e86&#xff0c;<br \/>\n    \/\/\u4f46\u662f\u56de\u8c03\u8fd8\u6ca1\u88ab\u8bbe\u7f6e&#xff0c;\u4ec0\u4e48\u6ca1\u505a\u5c31\u5173\u4e86&#xff0c;fd\u4e5f\u6ca1\u88ab\u91ca\u653e&#xff0c;\u6240\u4ee5\u4e0d\u80fd\u628a\u542f\u52a8\u8bfb\u4e8b\u4ef6\u76d1\u63a7\u653e\u5230\u6784\u9020\u51fd\u6570\u4e2d<br \/>\n    \/\/<br \/>\n    Acceptor(EventLoop* loop,uint16_t port):<br \/>\n            _socket(CreateServer(port)),<br \/>\n            _loop(loop),<br \/>\n            _channel(loop,_socket.Fd()){<br \/>\n            _channel.SetReadCallback(std::bind(&amp;Acceptor::HandleRead,this));<br \/>\n        }<br \/>\n        void SetAcceptCallback(const AcceptCallback&amp; cb){_accept_callback &#061; cb;}<br \/>\n        \/\/\u6240\u4ee5\u8981\u8bbe\u7f6e\u4e00\u4e2alisten\u63a5\u53e3\u3002\u4f7f\u7528\u8005\u624b\u52a8\u5f00\u59cb\u76d1\u542c\u3002<br \/>\n        void Listen(){_channel.EnableRead();}<br \/>\n}; <\/p>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u5177\u4f53\u6d41\u7a0b\u5c31\u662f&#xff0c;\u5728TcpServer\u4e2d\u8bbe\u7f6e_accept_callback\u2014\u2014\u5b9e\u9645\u4e0a\u5c31\u662f\u521b\u5efa\u8fde\u63a5\u7c7b\u7684\u51fd\u6570&#xff0c;\u261e\u540e\u5728Acceptor\u7684\u6784\u9020\u51fd\u6570\u4e2d\u8bbe\u7f6e\u76d1\u542c\u5957\u63a5\u5b57&#xff0c;\u628a\u76d1\u542c\u5957\u63a5\u5b57\u7684fd\u8bbe\u7f6e\u5230Channel\u4e2d\u4ee5\u53ca\u628acallback\u8bbe\u7f6e\u7ed9Channel&#xff0c;\u7136\u540e\u5728TcpServer\u4e2d\u542f\u52a8\u5bf9\u8bfb\u4e8b\u4ef6\u76d1\u63a7\u3002\u8fd9\u6837\u53ea\u8981\u6709\u5ba2\u6237\u7aef\u8fde\u63a5\u6765\u4e86&#xff0c;\u8bfb\u4e8b\u4ef6\u5c31\u4f1a\u5c31\u7eea&#xff0c;\u76f8\u5e94\u7684\u5c31\u4f1a\u5728EventLoop\u4e2d\u7684Start\u51fd\u6570\u4e2dPoll\u5c31\u68c0\u6d4b\u5230\u5c31\u7eea\u4e8b\u4ef6\u5c31\u4f1a\u5728Channel\u4e2d\u6267\u884c\u5c31\u7eea\u4e8b\u4ef6\u7684\u56de\u8c03\u51fd\u6570&#xff0c;\u7136\u540e\u6211\u8bbe\u7f6e\u7684\u56de\u8c03\u51fd\u6570\u662f\u7ed9\u5ba2\u6237\u7aef\u521b\u5efa\u65b0\u94fe\u63a5\u4e5f\u5c31\u662f\u521b\u5efa\u4e00\u4e2aConnection\u7c7b&#xff0c;\u6240\u4ee5\u5ba2\u6237\u7aef\u4e5f\u521b\u5efa\u6210\u529f\u4e86\u3002<\/p>\n<h4>4.5.2\u00a0Connection\u7c7b\u2014\u2014\u8fde\u63a5\u7ba1\u7406\u7c7b\/\u5ba2\u6237\u7aef\u8fde\u63a5\u7c7b<\/h4>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u8fd9\u5c31\u662f\u771f\u6b63\u7684\u5ba2\u6237\u7aef\u8fde\u63a5\u7c7b&#xff0c;\u5305\u542b\u81ea\u5b9a\u4e49\u7f13\u51b2\u533aBuffer\u3001\u8fde\u63a5\u5957\u63a5\u5b57\u3001\u8fde\u63a5\u4e8b\u4ef6\u7684\u7ba1\u7406Channel\u7c7b\u3001\u7c7b\u578b\u64e6\u9664\u7c7b(\u4fdd\u5b58\u8bf7\u6c42\u63a5\u6536\u5904\u7406\u7684\u4e0a\u4e0b\u6587)\u3001\u8fde\u63a5id(\u65b9\u4fbf\u6211\u4eecTcpServer\u7c7b\u7ba1\u7406)\u3001\u662f\u5426\u542f\u52a8\u6d3b\u8dc3\u9500\u6bc1\u6807\u5fd7\u3001EventLoop\u7c7b\u3001\u8fde\u63a5\u72b6\u6001\u7684\u679a\u4e3e\u3002\u5c24\u5176\u662f\u8fde\u63a5\u72b6\u6001\u7684\u679a\u4e3e&#xff0c;\u65b9\u4fbf\u6211\u4eec\u66f4\u52a0\u7075\u6d3b\u7684\u5904\u7406\u5404\u79cd\u51fd\u6570\u3002\u5176\u516c\u6709\u6210\u5458\u51fd\u6570\u5c31\u662f\u5c06\u79c1\u6709\u51fd\u6570\u5c01\u88c5\u5230\u4efb\u52a1\u961f\u5217\u91cc\u7136\u540e\u8c03\u7528\u3002\u5404\u79cd\u79c1\u6709\u51fd\u6570\u4e3b\u8981\u5c31\u662f&#xff1a;SendInLoop\u53d1\u9001\u6570\u636e\u3001ShutdownInLoop\u5173\u95ed\u8fde\u63a5\u3001\u5173\u95ed\u548c\u5f00\u542f\u8fde\u63a5\u7684\u975e\u6d3b\u8dc3\u9500\u6bc1\u3001\u7136\u540e\u5c31\u662f\u66f4\u65b0\u534f\u8bae(\u8fd9\u4e2a\u53ef\u80fd\u7528\u4e0d\u5230)\u3001\u5df2\u7ecf\u5404\u79cd\u8bbe\u7f6e\u7ed9Channel\u56de\u8c03\u51fd\u6570\u7684\u8bbe\u7f6e\u8bfb\u3001\u5199\u3001\u9519\u8bef\u3001\u4efb\u610f\u4e8b\u4ef6\u3001\u5173\u95ed\u3002\u6700\u540e\u5728\u5bf9\u5916\u7684\u516c\u5171\u63a5\u53e3\u5c31\u662f\u4e00\u4e9b\u5b89\u5168\u7684\u8bbf\u95ee\u79c1\u6709\u53d8\u91cf\u7684\u51fd\u6570&#xff0c;\u4ee5\u53caConnection\u7c7b\u4e2d\u56de\u8c03\u51fd\u6570\u7684\u8bbe\u7f6e\u3002<\/p>\n<p>\/\/\u8bbe\u7f6e\u8fde\u63a5\u72b6\u6001<br \/>\ntypedef enum {DISCONNECTED , CONNECTED , CONNECTING , DISCONNECTING}ConnStatu;<br \/>\n\/\/ DISCONNECTED &#8212; \u8fde\u63a5\u5173\u95ed\u8f6c\u6001<br \/>\n\/\/ ONNECTED &#8212; \u8fde\u63a5\u5efa\u7acb\u6210\u529f-\u5f85\u5904\u7406\u8f6c\u6001<br \/>\n\/\/ CONNECTING &#8212; \u8fde\u63a5\u5efa\u7acb\u5b8c\u6210&#xff0c;\u5404\u79cd\u8bbe\u7f6e\u5df2\u5b8c\u6210&#xff0c;\u53ef\u4ee5\u901a\u4fe1<br \/>\n\/\/ DISCONNECTING &#8212; \u5f85\u5173\u95ed\u72b6\u6001<\/p>\n<p>using PtrConnection &#061; std::shared_ptr&lt;Connection&gt;;<\/p>\n<p>\/\/\u4e00\u4e2a\u8fde\u63a5\u4e00\u4e2aConnection<br \/>\n\/\/\u53ea\u6709\u7ee7\u627f\u4e86enable_shared_from_this&lt;Connection&gt;\u624d\u80fd\u4f7f\u7528shared_from_this&#xff0c;\u8fd4\u56de\u4e00\u4e2a\u81ea\u5df1\u7684shared_ptr&#xff0c;enable_shared_from_this&lt;Connection&gt;\u5e95\u5c42\u662f\u5c01\u88c5\u4e86\u4e00\u4e2aweak_ptr&#xff0c;\u6240\u4ee5shared_ptr\u8ba1\u6570\u4e0d\u4f1a&#043;\u20141<br \/>\nclass Connection: public std::enable_shared_from_this&lt;Connection&gt;{<br \/>\n    private:<br \/>\n        uint64_t _conn_id;\/\/\u8fde\u63a5\u7684\u552f\u4e00ID&#xff0c;\u4fbf\u4e8e\u8fde\u63a5\u7684\u7ba1\u7406\u548c\u67e5\u627e,\u56e0\u4e3a_conn_id\u552f\u4e00\u6240\u4ee5\u6211\u4eec\u9ed8\u8ba4_time_id\u5c31\u662f_conn_id<br \/>\n        int _sockfd;\/\/\u8fde\u63a5\u5173\u8054\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26<br \/>\n        bool _enable_inactive_release; \/\/\u8fde\u63a5\u662f\u5426\u542f\u52a8\u975e\u6d3b\u8dc3\u9500\u6bc1\u7684\u5224\u65ad\u6807\u5fd7&#xff0c;\u9ed8\u8ba4\u4e3afalse<br \/>\n        \/\/\u8fd9\u91cc\u7684EventLoop\u8bbe\u7f6e\u7684\u662f\u6307\u9488\u539f\u56e0\u662f\u8fd9\u91cc\u7684loop\u662f\u7ebf\u7a0b\u6c60\u4e2d\u4f20\u8fc7\u6765\u7684loop\u3002\u5982\u679c\u76f4\u63a5\u8bbe\u7f6e\u4e3a\u5bf9\u8c61\u7684\u8bdd\u5c31\u4e0d\u662f\u7ebf\u7a0b\u6c60\u6a21\u5f0f\u4e86\u5931\u53bb\u4e86\u7ebf\u7a0b\u6c60\u7684\u4f18\u52bf\u4f1a\u9891\u7e41\u7684\u521b\u5efa\u548c\u9500\u6bc1\u7ebf\u7a0b\u2014\u2014\u8fd9\u8981\u4ece\u7528\u6237\u6001\u5207\u6362\u6210\u5185\u6838\u6001\u8017\u65f6<br \/>\n        \/\/\u7ebf\u7a0b\u6c60\u662f\u4e00\u76f4\u5b58\u5728\u5185\u5b58\u4e2d&#xff0c;\u4e5f\u907f\u514d\u4e86\u7f13\u5b58\u6c61\u67d3<br \/>\n        EventLoop *_loop;\/\/\u5173\u8054\u4e00\u4e2aEventLoop\u540c\u6837\u4e00\u4e2a\u8fde\u63a5\u7684\u51fd\u6570\u8c03\u7528\u5e94\u8be5\u662f\u7ebf\u7a0b\u5b89\u5168\u7684&#xff0c;\u6240\u4ee5\u540c\u6837\u8981\u5173\u8054\u4e00\u4e2aloop&#xff0c;\u56e0\u4e3a\u4e00\u4e2aloop\u5173\u8054\u4e00\u4e2a\u7ebf\u7a0b<br \/>\n        ConnStatu _statu;\/\/\u8fde\u63a5\u7684\u72b6\u6001<\/p>\n<p>        Socket _socket;\/\/\u521b\u5efasocket\u5957\u63a5\u5b57&#xff0c;\u8fdb\u884c\u57fa\u7840\u7684\u7f51\u7edc\u901a\u4fe1\u8bbe\u7f6e<br \/>\n        Channel _channel;\/\/\u8fde\u63a5\u7684\u4e8b\u4ef6\u7ba1\u7406<br \/>\n        Buffer _in_buffer;\/\/\u8f93\u5165\u7f13\u51b2\u533a<br \/>\n        Buffer _out_buffer;\/\/\u8f93\u51fa\u7f13\u51b2\u533a<br \/>\n        Any _context;\/\/\u8bf7\u6c42\u7684\u63a5\u6536\u5904\u7406\u4e0a\u4e0b\u6587<\/p>\n<p>        \/\/\u4e0b\u9762\u56db\u4e2a\u56de\u8c03\u51fd\u6570&#xff0c;\u662f\u8ba9\u7ec4\u4ef6\u4f7f\u7528\u8005(\u670d\u52a1\u5668\u6a21\u5757)\u6765\u8bbe\u7f6e\u7684&#8211;\u5176\u5b9e\u670d\u52a1\u5668\u6a21\u5757\u7684\u5904\u7406\u56de\u8c03\u4e5f\u662f\u7ec4\u4ef6\u4f7f\u7528\u8005\u8bbe\u7f6e\u7684<br \/>\n        using ConnectedCallback &#061; std::function&lt;void(const PtrConnection &amp;)&gt;;<br \/>\n        using MessageCallback &#061; std::function&lt;void(const PtrConnection &amp;,Buffer *)&gt;;<br \/>\n        using CloseCallback &#061; std::function&lt;void(const PtrConnection &amp;)&gt;;<br \/>\n        using AnyEventCallback &#061; std::function&lt;void(const PtrConnection &amp;)&gt;;<br \/>\n        ConnectedCallback _connected_callback;<br \/>\n        MessageCallback _message_callback;<br \/>\n        CloseCallback _closed_callback;<br \/>\n        AnyEventCallback _event_callback;<br \/>\n        \/\/\u989d\u5916\u8bbe\u7f6e\u7684\u4e0b\u9762\u8fd9\u4e2a\u662f\u2014\u2014\u7ec4\u4ef6\u5185\u8bbe\u7f6e\u7684\u8fde\u63a5\u5173\u95ed\u56de\u8c03\u2014\u2014\u7ec4\u4ef6\u5185\u8bbe\u7f6e\u7684&#xff0c;\u56e0\u4e3a\u670d\u52a1\u5668\u7ec4\u4ef6\u5185\u4f1a\u628a\u6240\u6709\u7684\u8fde\u63a5\u7ba1\u7406\u8d77\u6765&#xff0c;\u4e00\u65e6\u67d0\u4e2a\u8fde\u63a5\u8981\u5173\u95ed<br \/>\n        \/\/\u90a3\u4e48\u5c31\u5e94\u8be5\u4ece\u7ba1\u7406\u7684\u5730\u65b9\u79fb\u9664\u6389\u81ea\u5df1\u7684\u4fe1\u606f<br \/>\n        CloseCallback _server_closed_callback;<\/p>\n<p>        \/\/\u540c\u65f6\u8fd9\u4e9b\u56de\u8c03&#xff0c;\u4e00\u4e2a\u8fde\u63a5\u6240\u6709\u7684\u56de\u8c03\u90fd\u8981\u653e\u5230\u4efb\u52a1\u961f\u5217\u4e2d\u53bb&#xff0c;\u786e\u4fdd\u7ebf\u7a0b\u5b89\u5168<br \/>\n    private:<br \/>\n        \/\/\u6240\u4ee5\u9700\u8981\u8bbe\u7f6e\u4e00\u5806\u7684InLoop\u63a5\u53e3&#xff0c;\u628a\u56de\u8c03\u653e\u5165\u540c\u4e00\u4e2aloop\u4e2d\u7684\u540c\u4e00\u4e2a\u4efb\u52a1\u961f\u5217\u4e2d<\/p>\n<p>        \/\/\u8fde\u63a5\u83b7\u53d6\u4e4b\u540e&#xff0c;\u6240\u5728\u7684\u72b6\u6001\u4e0b\u8981\u8fdb\u884c\u5404\u79cd\u8bbe\u7f6e(\u7ed9Channel\u8bbe\u7f6e\u4e8b\u4ef6\u56de\u8c03&#xff0c;\u542f\u52a8\u8bfb\u76d1\u63a7)<br \/>\n        void EstablIsShedInLoop(){<br \/>\n            \/\/1.\u4fee\u6539\u8fde\u63a5\u72b6\u6001  2.\u542f\u52a8\u8bfb\u4e8b\u4ef6\u76d1\u63a7    3.\u8c03\u7528\u56de\u8c03\u51fd\u6570<br \/>\n            assert(_statu &#061;&#061; CONNECTING);\/\/\u5f53\u524d\u8fde\u63a5\u4e00\u5b9a\u662f\u7684\u534a\u8fde\u63a5\u72b6\u6001&#xff0c;\u8fd9\u6837\u6211\u624d\u53bb\u8bbe\u7f6e\u4e8b\u4ef6\u56de\u8c03<br \/>\n            _statu &#061; CONNECTED;\/\/\u5f53\u524d\u51fd\u6570\u6267\u884c\u5b8c\u6bd5&#xff0c;\u5219\u8fde\u63a5\u8fdb\u5165\u5df2\u5b8c\u6210\u8fde\u63a5\u72b6\u6001<br \/>\n            _channel.EnableRead();\/\/\u4e00\u65e6\u542f\u52a8\u8bfb\u4e8b\u4ef6\u76d1\u63a7\u5c31\u6709\u53ef\u80fd\u4f1a\u7acb\u5373\u89e6\u53d1\u8bfb\u4e8b\u4ef6&#xff0c;\u5982\u679c\u8fd9\u65f6\u5019\u542f\u52a8\u4e86\u975e\u6d3b\u8dc3\u8fde\u63a5\u9500\u6bc1<br \/>\n            if(_connected_callback)_connected_callback(shared_from_this());\/\/\u6709\u8fde\u63a5\u56de\u8c03\u51fd\u6570\u5c31\u89e6\u53d1\u5bf9\u5e94\u7684\u51fd\u6570<br \/>\n        }<\/p>\n<p>        \/\/\u5b9e\u9645\u7684\u91ca\u653e\u63a5\u53e3<br \/>\n        void ReleaseInLoop(){<br \/>\n            \/\/1.\u4fee\u6539\u8fde\u63a5\u72b6\u6001&#xff0c;\u5c06\u5176\u7f6e\u4e3aDISCONNECTED<br \/>\n            _statu&#061;DISCONNECTED;<br \/>\n            \/\/2.\u79fb\u9664\u8fde\u63a5\u7684\u4e8b\u4ef6\u76d1\u63a7<br \/>\n            _channel.Remove();<br \/>\n            \/\/3.\u5173\u95ed\u63cf\u8ff0\u7b26<br \/>\n            _socket.Close();<br \/>\n            \/\/4.\u5982\u679c\u5f53\u524d\u5b9a\u65f6\u5668\u961f\u5217\u4e2d\u8fd8\u6709\u5b9a\u65f6\u9500\u6bc1\u4efb\u52a1&#xff0c;\u5219\u53d6\u6d88\u4efb\u52a1<br \/>\n            if(_loop-&gt;HashTimer(_conn_id)) CancelInactiveReleaseInLoop();<br \/>\n            \/\/5.\u8c03\u7528\u5173\u95ed\u56de\u8c03\u51fd\u6570&#xff0c;\u907f\u514d\u5148\u79fb\u9664\u670d\u52a1\u5668\u7ba1\u7406\u7684\u8fde\u63a5\u4fe1\u606f\u5bfc\u81f4Connection\u88ab\u91ca\u653e&#xff0c;\u518d\u53bb\u5904\u7406\u4f1a\u51fa\u9519&#xff0c;\u56e0\u6b64\u5148\u8c03\u7528\u7528\u6237\u7684\u5173\u95ed\u670d\u52a1\u5668\u56de\u8c03\u51fd\u6570<br \/>\n            if(_closed_callback)_closed_callback(shared_from_this());<br \/>\n            \/\/6.\u8c03\u7528\u7ec4\u4ef6\u5185\u4e5f\u5c31\u662fConnection\u7684\u5173\u95ed\u56de\u8c03\u51fd\u6570<br \/>\n            if(_server_closed_callback)_server_closed_callback(shared_from_this());<br \/>\n        }<\/p>\n<p>        \/\/ void SendInLoop(const char* data,size_t len){<br \/>\n        \/\/     if(_statu &#061;&#061; DISCONNECTED)return ;<br \/>\n        \/\/     _out_buffer.WriteAndPush(data,len);<br \/>\n        \/\/     if(_channel.WriteAble()&#061;&#061;false){<br \/>\n        \/\/         _channel.EnableWrite();<br \/>\n        \/\/     }<br \/>\n        \/\/ }<br \/>\n        \/\/\u8fd9\u4e2a\u63a5\u53e3\u5e76\u4e0d\u662f\u5b9e\u9645\u7684\u53d1\u9001\u63a5\u53e3&#xff0c;\u800c\u53ea\u662f\u628a\u6570\u636e\u653e\u5230\u4e86\u53d1\u9001\u7f13\u51b2\u533a&#xff0c;\u56e0\u4e3a\u5df2\u7ecf\u542f\u52a8\u4e86\u53ef\u5199\u4e8b\u4ef6\u76d1\u63a7<br \/>\n        void SendInLoop(Buffer &amp;buf) {<br \/>\n            if (_statu &#061;&#061; DISCONNECTED) return ;<br \/>\n            _out_buffer.WriteBufferAndPush(buf);<br \/>\n            \/\/\u6211\u5199\u5230\u53d1\u9001\u7f13\u51b2\u533a\u4e86&#xff0c;\u5982\u679c\u6ca1\u6709\u76d1\u63a7\u5199\u7f13\u51b2\u533a\u5c31\u542f\u52a8\u76d1\u63a7<br \/>\n            if (_channel.WriteAble() &#061;&#061; false) {<br \/>\n                _channel.EnableWrite();<br \/>\n            }<br \/>\n        }<br \/>\n        void ShutdownInLoop(){<br \/>\n            _statu &#061; DISCONNECTING;\/\/\u8bbe\u7f6e\u8fde\u63a5\u4e3a\u534a\u5173\u95ed\u72b6\u6001<br \/>\n            if(_in_buffer.ReadAbleSize()&gt;0){<br \/>\n                if(_message_callback)_message_callback(shared_from_this(),&amp;_in_buffer);<br \/>\n            }<br \/>\n            \/\/\u8981\u4e48\u5c31\u662f\u5199\u5165\u6570\u636e\u7684\u65f6\u5019\u51fa\u9519\u5173\u95ed&#xff0c;\u8981\u4e48\u5c31\u662f\u4e48\u6709\u5f85\u53d1\u9001\u6570\u636e&#xff0c;\u76f4\u63a5\u5173\u95ed<br \/>\n            \/\/\u867d\u7136SendLoop\u51fd\u6570\u4e2d\u505a\u4e86\u5199\u4e8b\u4ef6\u76d1\u63a7\u7684\u5224\u65ad&#xff0c;\u4f46\u662f\u8fd9\u6837\u66f4\u52a0\u4f18\u96c5&#xff0c;\u9632\u6b62\u4ee3\u7801\u7455\u75b5\u3002\u66f4\u52a0\u5b89\u5168<br \/>\n            if(_out_buffer.ReadAbleSize()&gt;0){<br \/>\n                if(_channel.WriteAble() &#061;&#061; false){<br \/>\n                    _channel.EnableWrite();<br \/>\n                }<br \/>\n            }<br \/>\n            if(_out_buffer.ReadAbleSize() &#061;&#061; 0){<br \/>\n                Release();<br \/>\n            }<br \/>\n        }<br \/>\n        \/\/\u542f\u52a8\u975e\u6d3b\u8dc3\u8fde\u63a5\u8d85\u65f6\u91ca\u653e\u89c4\u5219<br \/>\n        void EnableInactiveReleaseInLoop(int sec){<br \/>\n            \/\/1.\u5c06\u5224\u65ad\u6807\u5fd7 _enable_inactive_release \u7f6e\u4e3atrue<br \/>\n            _enable_inactive_release &#061; true;<br \/>\n            \/\/2.\u5982\u679c\u5f53\u524d\u5b9a\u65f6\u9500\u6bc1\u4efb\u52a1\u5df2\u7ecf\u5b58\u5728&#xff0c;\u90a3\u5c31\u5237\u65b0\u4e00\u4e0b\u5ef6\u8fdf\u5373\u53ef<br \/>\n            if(_loop-&gt;HashTimer(_conn_id))return _loop-&gt;TimerRefresh(_conn_id);<br \/>\n            \/\/3.\u5982\u679c\u4e0d\u5b58\u5728\u5b9a\u65f6\u9500\u6bc1\u4efb\u52a1&#xff0c;\u5219\u65b0\u589e<br \/>\n            _loop-&gt;TimerAdd(_conn_id,sec,std::bind(&amp;Connection::Release,this));<br \/>\n        }<br \/>\n        \/\/\u53d6\u6d88\u975e\u6d3b\u8dc3\u8fde\u63a5\u8d85\u65f6\u91ca\u653e\u89c4\u5219<br \/>\n        void CancelInactiveReleaseInLoop(){<br \/>\n            _enable_inactive_release &#061; false;<br \/>\n            \/\/\u5b58\u5728\u5219\u53d6\u6d88<br \/>\n            if(_loop-&gt;HashTimer(_conn_id))return _loop-&gt;TimerCancel(_conn_id);<br \/>\n        }<br \/>\n        \/\/\u66f4\u65b0\u534f\u8bae<br \/>\n        void UpgradeInLoop(const Any &amp; context ,<br \/>\n            const ConnectedCallback&amp; conn,<br \/>\n            MessageCallback&amp; msg,<br \/>\n            CloseCallback&amp; closed,<br \/>\n            AnyEventCallback&amp; event){<br \/>\n                _context&#061;context;<br \/>\n                _connected_callback&#061;conn;<br \/>\n                _message_callback&#061;msg;<br \/>\n                _closed_callback&#061;closed;<br \/>\n                _event_callback&#061;event;<br \/>\n        }<\/p>\n<p>        \/\/\u9664\u6b64\u4e4b\u5916\u8fd8\u6709\u4e94\u4e2achannel\u7684\u4e8b\u4ef6\u56de\u8c03\u51fd\u6570<br \/>\n        \/\/\u89e6\u53d1\u53ef\u8bfb\u4e8b\u4ef6\u540e\u8c03\u7528\u7684\u51fd\u6570&#xff0c;\u63a5\u53d7socket\u6570\u636e\u653e\u5230\u63a5\u53d7\u7f13\u51b2\u533a\u4e2d&#xff0c;\u7136\u540e\u8c03\u7528_message_callback\u5904\u7406<br \/>\n        void HandleRead(){<br \/>\n            \/\/1.\u63a5\u53d7socket\u6570\u636e&#xff0c;\u653e\u5230\u7f13\u51b2\u533a<br \/>\n            char buf[65536];<br \/>\n            ssize_t ret &#061; _socket.NonBlockRecv(buf,65535);<br \/>\n            if(ret &lt; 0){<br \/>\n                \/\/\u51fa\u9519\u4e86&#xff0c;\u4e0d\u80fd\u76f4\u63a5\u5173\u95ed\u8fde\u63a5&#xff0c;\u8981\u770b\u6570\u636e\u8fd8\u6709\u6ca1\u6709\u8981\u5904\u7406\u7684\u6216\u5f85\u5904\u7406\u7684\u3002<br \/>\n                return ShutdownInLoop();\/\/\u7136\u540e\u5728\u51fd\u6570\u4e2d&#xff0c;\u5224\u65ad\u662f\u5426\u662f\u5f85\u5173\u95ed\u8fde\u63a5\u7684\u72b6\u6001\u3002\u8fd8\u6709\u5c31\u662f\u53ea\u6709\u8fde\u63a5\u5904\u7406\u5b8c\u540e\u624d\u53bb\u5b9a\u4e00\u4e2a\u52a0\u65f6\u6216\u8005\u5237\u65b0&#xff0c;\u4e0d\u7136\u6211\u8fde\u63a5\u4e1a\u52a1\u53ef\u80fd\u6ca1\u5904\u7406\u5b8c\u5c31\u8d85\u65f6\u5173\u95ed\u4e4b\u7c7b\u7684\u4e86<br \/>\n            }<br \/>\n            \/\/ else if(ret &#061;&#061; 0){<br \/>\n            \/\/     \/\/\u8fd9\u91cc\u7684\u7b49\u4e8e0\u8868\u793a\u7684\u662f\u6ca1\u6709\u8bfb\u53d6\u5230\u6570\u636e&#xff0c;\u800c\u5e76\u4e0d\u662f\u8fde\u63a5\u65ad\u5f00\u4e86&#xff0c;\u8fde\u63a5\u65ad\u5f00\u8fd4\u56de\u7684\u662f-1<br \/>\n            \/\/     \/\/\u4f46\u662f\u53ef\u4ee5\u4e0d\u5199\u56e0\u4e3a\u5728Write\u51fd\u6570\u4e2d\u6211\u4eec\u8fd8\u8bbe\u7f6e\u4e86ret&#061;&#061;0 \u5c31return\u7684\u60c5\u51b5\u3002<br \/>\n            \/\/     return;<br \/>\n            \/\/ }<br \/>\n            \/\/\u5c06\u6570\u636e\u653e\u5165\u8f93\u5165\u7f13\u51b2\u533a<br \/>\n            _in_buffer.WriteAndPush(buf,ret);<br \/>\n            \/\/2.\u8c03\u7528message_callback\u8fdb\u884c\u4e1a\u52a1\u5904\u7406<br \/>\n            if(_in_buffer.ReadAbleSize()&gt;0){<br \/>\n                \/\/shared_from_this&#8211;\u4ece\u5f53\u524d\u5bf9\u8c61\u81ea\u8eab\u83b7\u53d6\u81ea\u8eab\u7684shared_ptr\u7ba1\u7406\u5bf9\u8c61<br \/>\n                \/\/\u8fd9\u5c31\u662fret &#061;&#061;0 \u7684\u60c5\u51b5&#xff0c;\u4e0d\u8fc7\u6211\u5199\u4e86else if\u8fd9\u91cc\u6c38\u8fdc\u6210\u7acb &#xff0c;\u6709\u6570\u636e\u5c31\u8fdb\u884c\u4e1a\u52a1\u5904\u7406<br \/>\n                return _message_callback(shared_from_this(),&amp;_in_buffer);<br \/>\n            }<br \/>\n        }<br \/>\n        \/\/\u63cf\u8ff0\u7b26\u53ef\u5199\u4e8b\u4ef6\u89e6\u53d1\u540e\u8c03\u7528\u7684\u51fd\u6570&#xff0c;\u5c06\u53d1\u9001\u7f13\u51b2\u533a\u4e2d\u7684\u6570\u636e\u8fdb\u884c\u53d1\u9001\u3002<br \/>\n        void HandleWrite(){<br \/>\n            ssize_t ret &#061; _socket.NonBlockSend(_out_buffer.ReadPosition(),_out_buffer.ReadAbleSize());<br \/>\n            if(ret&lt;0){<br \/>\n                \/\/\u51fa\u9519\u4e86\u8981\u5173\u95ed<br \/>\n                \/\/\u4f46\u662f\u60f3\u8981\u628a\u7f13\u51b2\u533a\u4e2d\u7684\u6570\u636e\u5148\u5904\u7406\u4e86<br \/>\n                if(_in_buffer.ReadAbleSize()&gt;0){<br \/>\n                    _message_callback(shared_from_this(),&amp;_in_buffer);<br \/>\n                }<br \/>\n                \/\/\u6ca1\u6709\u5c31\u91ca\u653e<br \/>\n                return Release();\/\/\u8fd9\u65f6\u5019\u5c31\u662f\u5b9e\u9645\u7684\u5173\u95ed\u91ca\u653e\u64cd\u4f5c\u4e86\u3002\u56e0\u4e3a\u53d1\u9001\u5b8c\u4e86\u6211\u5c31\u4e0d\u9700\u8981\u7ee7\u7eed\u5904\u7406\u4e86\u3002<br \/>\n            }<br \/>\n            _out_buffer.MoveReadOffset(ret);\/\/\u8fd8\u8981\u5c06\u6211\u4eec\u7684\u8bfb\u504f\u79fb\u5411\u540e\u504f\u79fb<br \/>\n            if(_out_buffer.ReadAbleSize() &#061;&#061; 0){<br \/>\n                _channel.DisableWrite();\/\/\u5173\u95ed\u5199\u4e8b\u4ef6\u76d1\u63a7&#xff0c;\u7f13\u51b2\u533a\u5df2\u7ecf\u6ca1\u6709\u6570\u636e\u4e86&#xff0c;\u5c31\u4e0d\u8981\u76d1\u63a7\u5199\u4e86(\u4e0d\u65ad\u7684\u89e6\u53d1\u5199\u4e8b\u4ef6&#xff0c;\u53c8\u6ca1\u6709\u4e8b\u4ef6\u53ef\u5199LoopBusy)&#xff0c;LT\u6a21\u5f0f\u4e0b\u5982\u679c\u6709\u6570\u636e\u5c31\u4f1a\u4e00\u76f4\u63d0\u793a-ET<br \/>\n                \/\/\u56de\u987eepoll\u7684\u76d1\u63a7&#xff0c;\u63a5\u6536\u7f13\u51b2\u533a\u53ea\u8981\u6709\u6570\u636e\u53ef\u8bfb\u5c31\u89e6\u53d1\u8bfb\u4e8b\u4ef6&#xff0c;\u53d1\u9001\u7f13\u51b2\u533a\u53ea\u8981\u6709\u7a7a\u95f2\u7a7a\u95f4\u5c31\u89e6\u53d1\u5199\u4e8b\u4ef6\u3002<br \/>\n                \/\/\u5982\u679c\u5f53\u524d\u662f\u8fde\u63a5\u5f85\u5173\u95ed\u72b6\u6001&#xff0c;\u5219\u6709\u6570\u636e&#xff0c;\u53d1\u9001\u5b8c\u8fde\u63a5\u6570\u636e\u91ca\u653e\u8fde\u63a5&#xff0c;\u6ca1\u6709\u6570\u636e\u5219\u76f4\u63a5\u91ca\u653e<br \/>\n                if(_statu &#061;&#061; DISCONNECTING){<br \/>\n                    return Release();<br \/>\n                }<br \/>\n            }<br \/>\n            return;<br \/>\n        }<br \/>\n        \/\/\u63cf\u8ff0\u7b26\u89e6\u53d1\u6302\u65ad\u4e8b\u4ef6<br \/>\n        void HandleClose(){<br \/>\n            \/\/\u4e00\u65e6\u8fde\u63a5\u6302\u65ad\u4e86&#xff0c;\u5957\u63a5\u5b57\u5c31\u4ec0\u4e48\u90fd\u5e72\u4e0d\u4e86&#xff0c;\u56e0\u6b64\u6709\u6570\u636e\u5f85\u5904\u7406\u5c31\u5904\u7406\u4e00\u4e0b&#xff0c;\u5b8c\u6bd5\u5173\u95ed\u8fde\u63a5<br \/>\n            if(_in_buffer.ReadAbleSize()&gt;0){<br \/>\n                _message_callback(shared_from_this(),&amp;_in_buffer);<br \/>\n            }<br \/>\n            return Release();<br \/>\n        }<br \/>\n        \/\/\u63cf\u8ff0\u7b26\u89e6\u53d1\u51fa\u9519\u4e8b\u4ef6<br \/>\n        void HandleError(){<br \/>\n            return HandleClose();<br \/>\n        }<br \/>\n        \/\/\u63cf\u8ff0\u7b26\u89e6\u53d1\u4efb\u610f\u4e8b\u4ef6\u30021.\u5237\u65b0\u8fde\u63a5\u7684\u6d3b\u8dc3\u5ea6-\u5ef6\u8fdf\u5b9a\u65f6\u9500\u6bc1\u4efb\u52a1\u30022.\u8c03\u7528\u7ec4\u4ef6\u4f7f\u7528\u8005\u7684\u4efb\u610f\u4e8b\u4ef6\u56de\u8c03<br \/>\n        void HandleEvent(){<br \/>\n            \/\/\u542f\u52a8\u4e86\u975e\u6d3b\u8dc3\u9500\u6bc1<br \/>\n            if(_enable_inactive_release &#061;&#061; true){<br \/>\n                _loop-&gt;TimerRefresh(_conn_id);<br \/>\n            }<br \/>\n            if(_event_callback)_event_callback(shared_from_this());<br \/>\n        }<br \/>\n    public:<br \/>\n        Connection(EventLoop* loop,uint64_t conn_id ,int sockfd):_conn_id(conn_id),<br \/>\n            _sockfd(sockfd),_enable_inactive_release(false),_loop(loop),<br \/>\n            _statu(CONNECTING),_socket(_sockfd),_channel(loop,sockfd)<br \/>\n        {<br \/>\n            _channel.SetCloseCallback(std::bind(&amp;Connection::HandleClose,this));<br \/>\n            _channel.SetEventCallback(std::bind(&amp;Connection::HandleEvent,this));<br \/>\n            _channel.SetReadCallback(std::bind(&amp;Connection::HandleRead,this));<br \/>\n            _channel.SetErrorCallback(std::bind(&amp;Connection::HandleError,this));<br \/>\n            _channel.SetWriteCallback(std::bind(&amp;Connection::HandleWrite,this));<br \/>\n        }<br \/>\n        ~Connection(){DBG_LOG(&#034;\u91ca\u653e\u8fde\u63a5\u7c7b:%p&#034;,this);}<br \/>\n        \/\/\u53d1\u9001\u6570\u636e\u5230\u7f13\u51b2\u533a&#xff0c;\u542f\u52a8\u4e8b\u4ef6\u76d1\u63a7&#xff0c;\u56e0\u4e3a\u8fd9\u53ea\u662f\u7528\u6237\u8c03\u7528\u63a5\u53e3&#xff0c;\u6211\u4eec\u8fd8\u8981\u5904\u7406\u7f13\u51b2\u533a\u6570\u636e(\u534f\u8bae&#xff0c;\u7c98\u5305&#xff0c;\u662f\u5426\u5b8c\u6574\u7b49)&#xff0c;\u771f\u6b63\u53d1\u9001\u662fepoll\u76d1\u63a7\u5199\u4e8b\u4ef6\u540e\u8c03\u7528socket.send()\u53d1\u9001<br \/>\n        void Send(const char* data,size_t len){<br \/>\n            \/\/ _loop-&gt;RunInLoop(std::bind(&amp;Connection::SendInLoop,this,data,len));<br \/>\n            \/\/\u5916\u754c\u4f20\u5165\u7684data&#xff0c;\u53ef\u80fd\u662f\u4e2a\u4e34\u65f6\u7684\u7a7a\u95f4&#xff0c;\u6211\u4eec\u73b0\u5728\u53ea\u662f\u628a\u53d1\u9001\u64cd\u4f5c\u538b\u5165\u4e86\u4efb\u52a1\u6c60&#xff0c;\u6709\u53ef\u80fd\u5e76\u6ca1\u6709\u88ab\u7acb\u5373\u6267\u884c<br \/>\n            \/\/\u56e0\u6b64\u6709\u53ef\u80fd\u6267\u884c\u7684\u65f6\u5019&#xff0c;data\u6307\u5411\u7684\u7a7a\u95f4\u6709\u53ef\u80fd\u5df2\u7ecf\u88ab\u91ca\u653e\u4e86\u3002<br \/>\n            Buffer buf;<br \/>\n            buf.WriteAndPush(data, len);<br \/>\n            _loop-&gt;RunInLoop(std::bind(&amp;Connection::SendInLoop, this, std::move(buf)));<br \/>\n        }<br \/>\n        \/\/\u63d0\u4f9b\u7ed9\u7ec4\u4ef6\u4f7f\u7528\u8005\u7684\u5173\u95ed\u63a5\u53e3&#8211;\u5e76\u4e0d\u5b9e\u9645\u5173\u95ed&#xff0c;\u9700\u8981\u5224\u65ad\u6709\u6ca1\u6709\u6570\u636e\u5f85\u5904\u7406<br \/>\n        void Shutdown(){<br \/>\n            _loop-&gt;RunInLoop(std::bind(&amp;Connection::ShutdownInLoop,this));<br \/>\n        }<br \/>\n        void Release(){<br \/>\n            _loop-&gt;QueueInLoop(std::bind(&amp;Connection::ReleaseInLoop,this));<br \/>\n        }<br \/>\n        \/\/\u542f\u52a8\u975e\u6d3b\u8dc3\u9500\u6bc1&#xff0c;\u5e76\u5b9a\u4e49\u591a\u957f\u65f6\u95f4\u65e0\u901a\u4fe1\u5c31\u662f\u975e\u6d3b\u8dc3&#xff0c;\u6dfb\u52a0\u5b9a\u65f6\u4efb\u52a1<br \/>\n        void EnableInactiveRelease(int sec){<br \/>\n            _loop-&gt;RunInLoop(std::bind(&amp;Connection::EnableInactiveReleaseInLoop,this,sec));<br \/>\n        }<br \/>\n        \/\/\u53d6\u6d88\u975e\u6d3b\u8dc3\u9500\u6bc1<br \/>\n        void CancelInactiveRelease(){<br \/>\n            _loop-&gt;RunInLoop(std::bind(&amp;Connection::CancelInactiveReleaseInLoop,this));<br \/>\n        }<\/p>\n<p>        \/\/\u94fe\u63a5\u5efa\u7acb\u5c31\u7eea\u540e&#xff0c;\u8fdb\u884cChannel\u56de\u8c03\u8bbe\u7f6e&#xff0c;\u5e76\u8c03\u7528connect_cb<br \/>\n        void Established(){<br \/>\n            _loop-&gt;RunInLoop(std::bind(&amp;Connection::EstablIsShedInLoop,this));<br \/>\n        }<br \/>\n        \/\/\u5207\u6362\u534f\u8bae&#8211;\u91cd\u7f6e\u4e0a\u4e0b\u6587\u4ee5\u53ca\u9636\u6bb5\u6027\u5904\u7406\u51fd\u6570 &#8212; \u8fd9\u662f\u975e\u7ebf\u7a0b\u5b89\u5168\u7684&#xff0c;\u5fc5\u987b\u5728\u7ebf\u7a0b\u5f53\u4e2d\u7acb\u5373\u6267\u884c&#xff0c;\u9632\u6b62\u6211\u8981\u5728A\u540e\u5207\u6362\u534f\u8bae&#xff0c;\u4f46\u662f\u591a\u7ebf\u7a0b\u53ef\u80fdA\u8fd8\u6ca1\u7ed3\u675f\u534f\u8bae\u5148\u6267\u884c\u4e86\u534f\u8bae\u4e86\u8fd9\u79cd\u60c5\u51b5\u3002<br \/>\n        void Upgrade(const Any &amp; context,<br \/>\n            const ConnectedCallback&amp; conn,<br \/>\n            MessageCallback&amp; msg,<br \/>\n            CloseCallback&amp; closed,<br \/>\n            AnyEventCallback&amp; event){<br \/>\n            _loop-&gt;AssertInLoop();<br \/>\n            _loop-&gt;RunInLoop(std::bind(&amp;Connection::UpgradeInLoop,this,context,conn,msg,closed,event));<br \/>\n        }<\/p>\n<p>        \/\/\u5bf9\u4e8eConnection\u7684\u5176\u4f59\u63a5\u53e3<br \/>\n        \/\/\u6210\u5458\u521d\u59cb\u5316\u63a5\u53e3&#xff0c;\u83b7\u53d6\u6210\u5458\u63a5\u53e3<br \/>\n        int Fd(){return _sockfd;}<br \/>\n        int Id(){return _conn_id;}<br \/>\n        \/\/ ConnStatu Statu();\/\/\u8fd4\u56de\u4e00\u4e2a\u8fde\u63a5\u7684\u8f6c\u6001<br \/>\n        \/\/ \/\/\u4f46\u662f\u6211\u4eec\u771f\u6b63\u5173\u5fc3\u7684\u662f\u662f\u5426\u5904\u4e8e\u8fde\u63a5CONNECTED\u7684\u72b6\u6001<br \/>\n        bool Connected(){return (_statu &#061;&#061; CONNECTED);}<br \/>\n        \/\/\u83b7\u53d6\u4e0a\u4e0b\u6587\u4fe1\u606f&#xff0c;\u8fd4\u56de\u7684\u662f\u6307\u9488<br \/>\n        Any* GetContext(){return &amp;_context;}<br \/>\n        \/\/\u8bbe\u7f6e\u6210\u5458\u521d\u59cb\u5316<br \/>\n        void SetContext(const Any&amp; context){_context &#061; context;}<br \/>\n        \/\/\u8bbe\u7f6e\u4e0a\u4e0b\u6587\u4fe1\u606f&#xff0c;\u8fde\u63a5\u5efa\u7acb\u5b8c\u6210\u9636\u6bb5(???\u6216\u8005\u5047\u8bbe\u534f\u8bae\u5207\u6362\u4e86&#xff0c;\u540c\u6837\u4e5f\u8981\u628a\u4e4b\u524d\u7684\u4e0a\u4e0b\u6587\u4fe1\u606f\u4fee\u6539\u6210\u65b0\u7684\u534f\u8bae\u4e0a\u4e0b\u6587\u4fe1\u606f)<br \/>\n        void SetConnectedCallback(const ConnectedCallback&amp; cb){_connected_callback&#061;cb;}<br \/>\n        void SetMessageCallback(const MessageCallback&amp; cb){_message_callback&#061;cb;}<br \/>\n        void SetClosedCallback(const CloseCallback&amp; cb){_closed_callback&#061;cb;}<br \/>\n        void SetSrvClosedCallback(const CloseCallback&amp; cb){_server_closed_callback&#061;cb;}<br \/>\n        void SetAnyEventCallback(const AnyEventCallback&amp; cb){_event_callback&#061;cb;}<br \/>\n};      <\/p>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u6838\u5fc3\u8fd8\u662f\u5e95\u5c42\u7684Channel\u7c7bepoll\u5bf9\u5c31\u7eea\u4e8b\u4ef6\u7684\u7ba1\u7406&#xff0c;\u7279\u70b9\u662f\u8fd9\u91cc\u8fd8\u5904\u7406\u4e86\u591a\u7ebf\u7a0b\u4e5f\u5c31\u662f\u5355\u8fde\u63a5\u591a\u7ebf\u7a0b\u7684\u573a\u666f\u4e0b\u7684\u4efb\u52a1\u6c60\u5904\u7406\u3002<\/p>\n<h4 style=\"background-color:transparent\">4.5.3\u00a0TcpServer\u7c7b\u2014\u2014\u670d\u52a1\u5668\u5165\u53e3\u7c7b<\/h4>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 TcpServer\u7c7b\u5c31\u662f\u5bf9\u4e0a\u9762\u7684Acceptor\u7c7b\u548cConnection\u4ee5\u53ca\u7ebf\u7a0b\u6c60\u7684\u6838\u5fc3\u5c01\u88c5&#xff0c;\u7528_conns\u7ba1\u7406\u6240\u6709\u7684\u8fde\u63a5\u3002TcpServer\u7c7b\u5c31\u6bd4\u8f83\u7b80\u5355\u4e86\u5404\u79cd\u51fd\u6570\u5c31\u662f\u5bf9\u8fde\u63a5\u7684\u5904\u7406\u51fd\u6570&#xff0c;\u4ee5\u53ca\u6dfb\u52a0\u5b9a\u65f6\u4efb\u52a1\u3002\u6700\u6838\u5fc3\u7684\u5c31\u662fNewConnection\u51fd\u6570\u8bbe\u7f6e\u7ed9Acceptor\u7136\u540eAcceptor\u624d\u53ef\u4ee5\u5728\u65b0\u8fde\u63a5\u6765\u7684\u65f6\u5019\u521b\u5efaConnection\u7c7b\u7ed9\u65b0\u5ba2\u6237\u7aef\u3002\u4ee3\u7801\u5982\u4e0b&#xff1a;<\/p>\n<p>class TcpServer{<br \/>\n    private:<br \/>\n        uint64_t _next_id;      \/\/\u81ea\u52a8\u589e\u957f\u7684\u8fde\u63a5ID<br \/>\n        int _port;              \/\/\u670d\u52a1\u5668\u6240\u6302\u8f7d\u7684\u7aef\u53e3<br \/>\n        int _timeout;           \/\/\u975e\u6d3b\u8dc3\u94fe\u63a5\u7684\u7edf\u8ba1\u65f6\u95f4<br \/>\n        \/\/\u5728_acceptor\u4e4b\u524d\u6211\u4eec\u8981\u628a_baseloop\u5b9e\u4f8b\u5316\u51fa\u6765<br \/>\n        EventLoop _baseloop;    \/\/\u4e3b\u7ebf\u7a0b\u7684EventLoop\u5bf9\u8c61&#xff0c;\u8d1f\u8d23\u76d1\u542c\u4e8b\u4ef6\u7684\u5904\u7406<br \/>\n        Acceptor _acceptor;     \/\/\u76d1\u542c\u5957\u63a5\u5b57\u7684\u7ba1\u7406\u5bf9\u8c61<br \/>\n        LoopThreadPoll _pool;   \/\/\u4ece\u5c5eEventLoop\u7684\u7ebf\u7a0b\u6c60<br \/>\n        bool _enable_inactive_release;\/\/\u662f\u5426\u542f\u52a8\u4e86\u975e\u6d3b\u8dc3\u94fe\u63a5\u9500\u6bc1\u7684\u5224\u65ad\u6807\u5fd7<br \/>\n        std::unordered_map&lt;uint64_t,PtrConnection&gt; _conns;\/\/\u4fdd\u5b58\u7ba1\u7406\u6240\u6709\u8fde\u63a5\u5bf9\u5e94\u7684shared_ptr\u5bf9\u8c61<br \/>\n    private:<br \/>\n        \/\/\u56de\u8c03\u51fd\u6570\u2014\u2014Connection\u7684\u56de\u8c03\u51fd\u6570<br \/>\n        using ConnectedCallback &#061; std::function&lt;void(const PtrConnection &amp;)&gt;;<br \/>\n        using MessageCallback &#061; std::function&lt;void(const PtrConnection &amp;,Buffer *)&gt;;<br \/>\n        using CloseCallback &#061; std::function&lt;void(const PtrConnection &amp;)&gt;;<br \/>\n        using AnyEventCallback &#061; std::function&lt;void(const PtrConnection &amp;)&gt;;<br \/>\n        ConnectedCallback _connected_callback;<br \/>\n        MessageCallback _message_callback;<br \/>\n        CloseCallback _closed_callback;<br \/>\n        AnyEventCallback _event_callback;<br \/>\n    private:<br \/>\n        void RemoveConnectionInLoop(const PtrConnection &amp;conn){<br \/>\n            int id&#061;conn-&gt;Id();<br \/>\n            auto it&#061;_conns.find(id);<br \/>\n            if(it!&#061;_conns.end())<br \/>\n                _conns.erase(id);<br \/>\n        }<br \/>\n        \/\/\u4ece\u7ba1\u7406\u7684_conns\u4e2d\u79fb\u9664\u5bf9\u5e94\u8fde\u63a5\u4fe1\u606f&#xff0c;\u8fd9\u4e2a\u8fde\u63a5\u624d\u4f1a\u771f\u6b63\u7684\u91ca\u653e\u3002\u8fd9\u5b9e\u9645\u4e0a\u5c31\u662f\u670d\u52a1\u5668\u4e2d\u7684close\u4e5f\u5c31\u662fSrvClosedCallback<br \/>\n        void RemoveConnection(const PtrConnection &amp;conn){<br \/>\n            _baseloop.RunInLoop(std::bind(&amp;TcpServer::RemoveConnectionInLoop,this,conn));<br \/>\n        }<br \/>\n        \/\/\u4e3a\u65b0\u94fe\u63a5\u6784\u9020\u4e00\u4e2aConnection\u8fdb\u884c\u7ba1\u7406<br \/>\n        void NewConnection(int fd){<br \/>\n            _next_id&#043;&#043;;<br \/>\n            PtrConnection conn(new Connection(_pool.NextLoop(), _next_id,fd));<br \/>\n            \/\/\u8fd9\u91cc\u7684\u8bbe\u7f6e\u987a\u5e8f\u4e0d\u80fd\u4e71&#xff0c;\u56e0\u4e3a\u5728Established\u51fd\u6570\u4e2d\u4f1a\u5148\u8c03\u7528Message_cb\u51fd\u6570\u6240\u4ee5Message<br \/>\n            conn-&gt;SetMessageCallback(_message_callback);<br \/>\n            conn-&gt;SetClosedCallback(_closed_callback);<br \/>\n            conn-&gt;SetConnectedCallback(_connected_callback);<br \/>\n            conn-&gt;SetAnyEventCallback(_event_callback);<br \/>\n            conn-&gt;SetSrvClosedCallback(std::bind(&amp;TcpServer::RemoveConnection,this,std::placeholders::_1));<br \/>\n            if(_enable_inactive_release)conn-&gt;EnableInactiveRelease(_timeout);<br \/>\n            conn-&gt;Established();<br \/>\n            _conns.insert(std::make_pair(_next_id,conn));\/\/\u7ba1\u7406\u8d77\u6765\u4e0d\u7136\u76f4\u63a5\u91ca\u653e\u4e86\u5c31\u7528\u4e0d\u4e86\u4e86<br \/>\n        }<\/p>\n<p>        \/\/\u6dfb\u52a0\u5b9a\u65f6\u4efb\u52a1<br \/>\n        void RunAfterInLoop(const Functor&amp; task,int delay){<br \/>\n            _next_id&#043;&#043;;<br \/>\n            _baseloop.TimerAdd(_next_id,delay,task);<br \/>\n        }<br \/>\n    public:<br \/>\n        TcpServer(int port):_next_id(0),_port(port),_timeout(5),\/\/\u9ed8\u8ba45s<br \/>\n                            _acceptor(&amp;_baseloop,_port),<br \/>\n                            _pool(&amp;_baseloop),<br \/>\n                            _enable_inactive_release(false){<br \/>\n                            \/\/ _acceptor.Listen();\/\/Listen\u4e0d\u80fd\u6302\u5230\u8fd9\u91cc\u56e0\u4e3a\u670d\u52a1\u5668\u7684\u5176\u4ed6\u8bbe\u7f6e\u8fd8\u6ca1\u8bbe\u7f6e\u597d<br \/>\n                            \/\/ _pool.Create();\/\/\u521b\u5efa\u7ebf\u7a0b\u6c60\u7684\u4ece\u5c5e\u7ebf\u7a0b,\u4f46\u662f\u4e0d\u80fd\u653e\u5230\u6784\u5efa\u51fd\u6570\u4e2d&#xff0c;\u56e0\u4e3a\u6b64\u65f6\u8fd8\u6ca1\u6709\u8bbe\u7f6eSetThreadCount\u6240\u4ee5\u7ebf\u7a0b\u6570\u91cf\u9ed8\u8ba4\u662f0<br \/>\n                            _acceptor.SetAcceptCallback(std::bind(&amp;TcpServer::NewConnection,this,std::placeholders::_1));<br \/>\n                            _acceptor.Listen();\/\/\u5c06\u76d1\u542c\u5957\u63a5\u5b57\u6302\u5230baseloop\u4e0a\u5f00\u59cb\u76d1\u63a7\u4e8b\u4ef6<br \/>\n        }<br \/>\n        void SetThreadCount(int count){_pool.SetThreadCount(count);}<br \/>\n        void Start(){_pool.Create();_baseloop.Start();}<br \/>\n        void EnableInactiveRelease(int timeout){_timeout&#061;timeout;_enable_inactive_release&#061;true;}<br \/>\n        \/\/\u7528\u4e8e\u6dfb\u52a0\u4e00\u4e2a\u5b9a\u65f6\u4efb\u52a1<br \/>\n        void RunAfter(const Functor&amp; task,int delay){<br \/>\n            _baseloop.RunInLoop(std::bind(&amp;TcpServer::RunAfterInLoop,this,task,delay));<br \/>\n        }<br \/>\n        \/\/\u8bbe\u7f6e\u56de\u8c03\u51fd\u6570<br \/>\n        void SetConnectedCallback(const ConnectedCallback&amp; cb){_connected_callback&#061;cb;}<br \/>\n        void SetMessageCallback(const MessageCallback&amp; cb){_message_callback&#061;cb;}<br \/>\n        void SetClosedCallback(const CloseCallback&amp; cb){_closed_callback&#061;cb;}<br \/>\n        void SetAnyEventCallback(const AnyEventCallback&amp; cb){_event_callback&#061;cb;}<br \/>\n};<\/p>\n<h2>\u4e94&#xff1a;\u9879\u76ee\u603b\u7ed3<\/h2>\n<p>\u00a0 \u00a0 \u00a0 \u00a0 \u4e00\u4e2a\u5b8c\u6574\u7684\u4effmuduo\u5e93\u7684\u9ad8\u6027\u80fd\u670d\u52a1\u5668\u9879\u76ee\u4ee3\u7801\u5c31\u662f\u8fd9\u6837&#xff0c;\u6574\u4f53\u770b\u4e0b\u6765\u6838\u5fc3\u6280\u672f\u548c\u6574\u4f53\u7684\u6846\u67b6\u4e4b\u95f4\u7684\u8054\u7cfb\u8fd8\u662f\u6bd4\u8f83\u901a\u900f\u7684&#xff0c;\u6700\u4e3b\u8981\u7684\u6838\u5fc3\u5c31\u662fChannel\u7c7b\u548cEventLoop\u7c7b&#xff0c;Channel\u662fepoll\u7684\u6838\u5fc3\u8d1f\u8d23\u5bf9\u4e8b\u4ef6\u7684\u76d1\u63a7\u5df2\u7ecf\u8fd4\u56de\u5c31\u7eea\u4e8b\u4ef6&#xff0c;EventLoop\u662fReactor\u7684\u6838\u5fc3\u8d1f\u8d23\u83b7\u53d6\u5c31\u7eea\u4e8b\u4ef6\u548c\u5bf9\u5c31\u7eea\u4e8b\u4ef6\u7684\u5904\u7406\u5df2\u7ecf\u5bf9\u4efb\u52a1\u6c60\u4e2d\u7684\u4efb\u52a1\u5904\u7406\u3002<\/p>\n<h5>\u6838\u5fc3\u6280\u672f\u4eae\u70b9<\/h5>\n<ul>\n<li>\u7ebf\u7a0b\u6a21\u578b\u4f18\u5316&#xff1a;LoopThreadPoll \u5b9e\u73b0\u8fde\u63a5\u7684 RR \u8f6e\u8be2\u5206\u914d&#xff0c;\u5145\u5206\u5229\u7528\u591a\u6838 CPU&#xff0c;\u89e3\u51b3\u5355\u7ebf\u7a0b Reactor \u7684\u6027\u80fd\u74f6\u9888&#xff1b;<\/li>\n<li>\u5b9a\u65f6\u5668\u9ad8\u6548\u5b9e\u73b0&#xff1a;\u57fa\u4e8e timerfd \u7684\u5355\u5c42\u65f6\u95f4\u8f6e\u5b9a\u65f6\u5668&#xff0c;O (1) \u65f6\u95f4\u590d\u6742\u5ea6\u5904\u7406\u77ed\u5b9a\u65f6\u4efb\u52a1&#xff0c;\u9002\u914d\u8fde\u63a5\u8d85\u65f6\u573a\u666f&#xff1b;<\/li>\n<li>\u534f\u8bae\u7075\u6d3b\u9002\u914d&#xff1a;Any \u7c7b\u5b9e\u73b0\u7c7b\u578b\u64e6\u9664&#xff0c;\u652f\u6301 HTTP \/ \u81ea\u5b9a\u4e49\u534f\u8bae\u7684\u4e0a\u4e0b\u6587\u5b58\u50a8&#xff0c;\u65e0\u9700\u4fee\u6539\u6846\u67b6\u5373\u53ef\u6269\u5c55\u65b0\u534f\u8bae&#xff1b;<\/li>\n<li>IO \u4e8b\u4ef6\u5b89\u5168\u5904\u7406&#xff1a;ET \u6a21\u5f0f &#043; \u975e\u963b\u585e fd \u7684\u7ec4\u5408&#xff0c;\u907f\u514d\u6570\u636e\u6b8b\u7559\u548c\u7ebf\u7a0b\u5361\u6b7b&#xff0c;\u4fdd\u8bc1\u9ad8\u5e76\u53d1\u4e0b\u7684\u7a33\u5b9a\u6027\u3002<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>\u524d\u8a00&#xff1a; \u672c\u6587\u5b9e\u73b0\u7684\u662f\u4e00\u4e2a\u4effmuduo\u5e93\u6838\u5fc3\u8bbe\u8ba1\u7684\u9ad8\u6027\u80fdTCP\u670d\u52a1\u5668&#xff0c;\u57fa\u4e8e\u591aReactor\u6a21\u5f0fepoll\u591a\u7ebf\u7a0b\u65f6\u95f4\u8f6e\u5b9a\u65f6\u5668&#xff0c;\u8986\u76d6Linux\/C\u7f51\u7edc\u7f16\u7a0b\u6838\u5fc3\u77e5\u8bc6\u70b9\u3002 \u4f5c\u4e3a\u5b66\u4e60\u5b8cC\/Linux\u540e\u7684\u5b9e\u6218\u9879\u76ee&#xff0c;\u68b3\u7406\u5e95\u5c42\u7f51\u7edc\u6846\u67b6\u7684\u8bbe\u8ba1\u601d\u8def&#xff0c;\u4e5f\u4e3a\u5b9e\u4e60\u6c42\u804c\u592f\u5b9e\u5e95\u5c42\u7f16\u7a0b\u80fd\u529b\u3002 \u8bfb\u5b8c\u672c\u6587\u5e0c\u671b\u80fd\u5e2e\u4f60\u7406\u89e3\u591aReactor\u6a21\u5f0f\u7684\u843d\u5730\u5b9e\u73b0\u3001muduo\u6838\u5fc3\u6a21\u5757\u7684\u8bbe\u8ba1\u903b\u8f91&#xff0c;\u4ee5\u53caLinux\u7f51\u7edc\u7f16\u7a0b\u7684\u5173\u952e\u5751\u70b9\u3002\u9879\u76ee\u6e90\u7801gitee<\/p>\n","protected":false},"author":2,"featured_media":66700,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[55,3884,58,205,43],"topic":[],"class_list":["post-66701","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-server","tag-c","tag-epoll","tag-linux","tag-tcp-ip","tag-43"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u3010C++\/Linux\u5b9e\u6218\u9879\u76ee\u3011\u4effmuduo\u5e93\u5b9e\u73b0\u9ad8\u6027\u80fdReactor\u6a21\u5f0fTCP\u670d\u52a1\u5668\uff08\u6df1\u5ea6\u89e3\u6790\uff09 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.wsisp.com\/helps\/66701.html\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u3010C++\/Linux\u5b9e\u6218\u9879\u76ee\u3011\u4effmuduo\u5e93\u5b9e\u73b0\u9ad8\u6027\u80fdReactor\u6a21\u5f0fTCP\u670d\u52a1\u5668\uff08\u6df1\u5ea6\u89e3\u6790\uff09 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"og:description\" content=\"\u524d\u8a00&#xff1a; \u672c\u6587\u5b9e\u73b0\u7684\u662f\u4e00\u4e2a\u4effmuduo\u5e93\u6838\u5fc3\u8bbe\u8ba1\u7684\u9ad8\u6027\u80fdTCP\u670d\u52a1\u5668&#xff0c;\u57fa\u4e8e\u591aReactor\u6a21\u5f0fepoll\u591a\u7ebf\u7a0b\u65f6\u95f4\u8f6e\u5b9a\u65f6\u5668&#xff0c;\u8986\u76d6Linux\/C\u7f51\u7edc\u7f16\u7a0b\u6838\u5fc3\u77e5\u8bc6\u70b9\u3002 \u4f5c\u4e3a\u5b66\u4e60\u5b8cC\/Linux\u540e\u7684\u5b9e\u6218\u9879\u76ee&#xff0c;\u68b3\u7406\u5e95\u5c42\u7f51\u7edc\u6846\u67b6\u7684\u8bbe\u8ba1\u601d\u8def&#xff0c;\u4e5f\u4e3a\u5b9e\u4e60\u6c42\u804c\u592f\u5b9e\u5e95\u5c42\u7f16\u7a0b\u80fd\u529b\u3002 \u8bfb\u5b8c\u672c\u6587\u5e0c\u671b\u80fd\u5e2e\u4f60\u7406\u89e3\u591aReactor\u6a21\u5f0f\u7684\u843d\u5730\u5b9e\u73b0\u3001muduo\u6838\u5fc3\u6a21\u5757\u7684\u8bbe\u8ba1\u903b\u8f91&#xff0c;\u4ee5\u53caLinux\u7f51\u7edc\u7f16\u7a0b\u7684\u5173\u952e\u5751\u70b9\u3002\u9879\u76ee\u6e90\u7801gitee\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.wsisp.com\/helps\/66701.html\" \/>\n<meta property=\"og:site_name\" content=\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"article:published_time\" content=\"2026-01-27T03:25:12+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/01\/20260127032509-697830154d07b.jpg\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"26 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/66701.html\",\"url\":\"https:\/\/www.wsisp.com\/helps\/66701.html\",\"name\":\"\u3010C++\/Linux\u5b9e\u6218\u9879\u76ee\u3011\u4effmuduo\u5e93\u5b9e\u73b0\u9ad8\u6027\u80fdReactor\u6a21\u5f0fTCP\u670d\u52a1\u5668\uff08\u6df1\u5ea6\u89e3\u6790\uff09 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"isPartOf\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\"},\"datePublished\":\"2026-01-27T03:25:12+00:00\",\"dateModified\":\"2026-01-27T03:25:12+00:00\",\"author\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/66701.html#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.wsisp.com\/helps\/66701.html\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/66701.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.wsisp.com\/helps\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u3010C++\/Linux\u5b9e\u6218\u9879\u76ee\u3011\u4effmuduo\u5e93\u5b9e\u73b0\u9ad8\u6027\u80fdReactor\u6a21\u5f0fTCP\u670d\u52a1\u5668\uff08\u6df1\u5ea6\u89e3\u6790\uff09\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\",\"url\":\"https:\/\/www.wsisp.com\/helps\/\",\"name\":\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"description\":\"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"contentUrl\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"caption\":\"admin\"},\"sameAs\":[\"http:\/\/wp.wsisp.com\"],\"url\":\"https:\/\/www.wsisp.com\/helps\/author\/admin\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"\u3010C++\/Linux\u5b9e\u6218\u9879\u76ee\u3011\u4effmuduo\u5e93\u5b9e\u73b0\u9ad8\u6027\u80fdReactor\u6a21\u5f0fTCP\u670d\u52a1\u5668\uff08\u6df1\u5ea6\u89e3\u6790\uff09 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.wsisp.com\/helps\/66701.html","og_locale":"zh_CN","og_type":"article","og_title":"\u3010C++\/Linux\u5b9e\u6218\u9879\u76ee\u3011\u4effmuduo\u5e93\u5b9e\u73b0\u9ad8\u6027\u80fdReactor\u6a21\u5f0fTCP\u670d\u52a1\u5668\uff08\u6df1\u5ea6\u89e3\u6790\uff09 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","og_description":"\u524d\u8a00&#xff1a; \u672c\u6587\u5b9e\u73b0\u7684\u662f\u4e00\u4e2a\u4effmuduo\u5e93\u6838\u5fc3\u8bbe\u8ba1\u7684\u9ad8\u6027\u80fdTCP\u670d\u52a1\u5668&#xff0c;\u57fa\u4e8e\u591aReactor\u6a21\u5f0fepoll\u591a\u7ebf\u7a0b\u65f6\u95f4\u8f6e\u5b9a\u65f6\u5668&#xff0c;\u8986\u76d6Linux\/C\u7f51\u7edc\u7f16\u7a0b\u6838\u5fc3\u77e5\u8bc6\u70b9\u3002 \u4f5c\u4e3a\u5b66\u4e60\u5b8cC\/Linux\u540e\u7684\u5b9e\u6218\u9879\u76ee&#xff0c;\u68b3\u7406\u5e95\u5c42\u7f51\u7edc\u6846\u67b6\u7684\u8bbe\u8ba1\u601d\u8def&#xff0c;\u4e5f\u4e3a\u5b9e\u4e60\u6c42\u804c\u592f\u5b9e\u5e95\u5c42\u7f16\u7a0b\u80fd\u529b\u3002 \u8bfb\u5b8c\u672c\u6587\u5e0c\u671b\u80fd\u5e2e\u4f60\u7406\u89e3\u591aReactor\u6a21\u5f0f\u7684\u843d\u5730\u5b9e\u73b0\u3001muduo\u6838\u5fc3\u6a21\u5757\u7684\u8bbe\u8ba1\u903b\u8f91&#xff0c;\u4ee5\u53caLinux\u7f51\u7edc\u7f16\u7a0b\u7684\u5173\u952e\u5751\u70b9\u3002\u9879\u76ee\u6e90\u7801gitee","og_url":"https:\/\/www.wsisp.com\/helps\/66701.html","og_site_name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","article_published_time":"2026-01-27T03:25:12+00:00","og_image":[{"url":"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/01\/20260127032509-697830154d07b.jpg"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"admin","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"26 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.wsisp.com\/helps\/66701.html","url":"https:\/\/www.wsisp.com\/helps\/66701.html","name":"\u3010C++\/Linux\u5b9e\u6218\u9879\u76ee\u3011\u4effmuduo\u5e93\u5b9e\u73b0\u9ad8\u6027\u80fdReactor\u6a21\u5f0fTCP\u670d\u52a1\u5668\uff08\u6df1\u5ea6\u89e3\u6790\uff09 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","isPartOf":{"@id":"https:\/\/www.wsisp.com\/helps\/#website"},"datePublished":"2026-01-27T03:25:12+00:00","dateModified":"2026-01-27T03:25:12+00:00","author":{"@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41"},"breadcrumb":{"@id":"https:\/\/www.wsisp.com\/helps\/66701.html#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.wsisp.com\/helps\/66701.html"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.wsisp.com\/helps\/66701.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.wsisp.com\/helps"},{"@type":"ListItem","position":2,"name":"\u3010C++\/Linux\u5b9e\u6218\u9879\u76ee\u3011\u4effmuduo\u5e93\u5b9e\u73b0\u9ad8\u6027\u80fdReactor\u6a21\u5f0fTCP\u670d\u52a1\u5668\uff08\u6df1\u5ea6\u89e3\u6790\uff09"}]},{"@type":"WebSite","@id":"https:\/\/www.wsisp.com\/helps\/#website","url":"https:\/\/www.wsisp.com\/helps\/","name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","description":"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41","name":"admin","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/","url":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","contentUrl":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","caption":"admin"},"sameAs":["http:\/\/wp.wsisp.com"],"url":"https:\/\/www.wsisp.com\/helps\/author\/admin"}]}},"_links":{"self":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/66701","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/comments?post=66701"}],"version-history":[{"count":0,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/66701\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media\/66700"}],"wp:attachment":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media?parent=66701"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/categories?post=66701"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/tags?post=66701"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/topic?post=66701"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}