{"id":677,"date":"2025-11-17T22:06:53","date_gmt":"2025-11-17T14:06:53","guid":{"rendered":"http:\/\/www.tgwttt.xyz\/?p=677"},"modified":"2025-11-17T22:06:55","modified_gmt":"2025-11-17T14:06:55","slug":"%e5%bd%bb%e5%ba%95%e6%90%9e%e6%87%82io%e5%a4%9a%e8%b7%af%e5%a4%8d%e7%94%a8selectpollepoll","status":"publish","type":"post","link":"https:\/\/www.tgwttt.xyz\/?p=677","title":{"rendered":"\u5f7b\u5e95\u641e\u61c2IO\u591a\u8def\u590d\u7528(select,poll,epoll)"},"content":{"rendered":"\n<p>select and poll\u4ee3\u7801\u793a\u4f8b\uff1a<a href=\"https:\/\/gitee.com\/tgwTTT\/linux-learning-dai\/tree\/master\/select\">https:\/\/gitee.com\/tgwTTT\/linux-learning-dai\/tree\/master\/select<\/a><\/p>\n\n\n\n<p>epoll\u4ee3\u7801\u793a\u4f8b\uff1a<a href=\"https:\/\/gitee.com\/tgwTTT\/linux-learning-dai\/tree\/master\/Tcpepollserver\">https:\/\/gitee.com\/tgwTTT\/linux-learning-dai\/tree\/master\/Tcpepollserver<\/a><\/p>\n\n\n\n<p>\u5728 Linux \u7f51\u7edc\u7f16\u7a0b\u4e2d\uff0cI\/O \u591a\u8def\u590d\u7528\u662f\u5b9e\u73b0\u9ad8\u5e76\u53d1\u670d\u52a1\u5668\u7684\u6838\u5fc3\u6280\u672f\u4e4b\u4e00\u3002\u800c <code>select<\/code> \u4f5c\u4e3a\u6700\u53e4\u8001\u7684\u7cfb\u7edf\u8c03\u7528\u4e4b\u4e00\uff0c\u5c3d\u7ba1\u5728\u4eca\u5929\u5df2\u88ab <code>epoll<\/code> \u7b49\u66f4\u9ad8\u6548\u7684\u673a\u5236\u53d6\u4ee3\uff0c\u4f46\u4f9d\u7136\u662f\u5b66\u4e60\u7f51\u7edc\u7f16\u7a0b\u7684\u5fc5\u7ecf\u4e4b\u8def\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Select<\/strong>:<\/h2>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"449\" height=\"204\" src=\"http:\/\/www.tgwttt.xyz\/wp-content\/uploads\/2025\/11\/image-7.png\" alt=\"\" class=\"wp-image-678\" srcset=\"https:\/\/www.tgwttt.xyz\/wp-content\/uploads\/2025\/11\/image-7.png 449w, https:\/\/www.tgwttt.xyz\/wp-content\/uploads\/2025\/11\/image-7-300x136.png 300w\" sizes=\"auto, (max-width: 449px) 100vw, 449px\" \/><\/figure>\n\n\n\n<p><strong>\u521d\u8bc6select\uff1a<\/strong><\/p>\n\n\n\n<p><code>select<\/code> \u662f\u4e00\u4e2a\u540c\u6b65 I\/O \u591a\u8def\u590d\u7528\u673a\u5236\uff0c\u5141\u8bb8\u7a0b\u5e8f\u5728\u4e00\u4e2a\u7ebf\u7a0b\u5185\u540c\u65f6\u76d1\u89c6\u591a\u4e2a\u6587\u4ef6\u63cf\u8ff0\u7b26\uff08file descriptor\uff0c\u7b80\u79f0 fd\uff09\uff0c\u7b49\u5f85\u5176\u4e2d\u67d0\u4e9b fd \u53d8\u4e3a\u201c\u53ef\u8bfb\u201d\u3001\u201c\u53ef\u5199\u201d\u6216\u201c\u53d1\u751f\u5f02\u5e38\u201d\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;sys\/select.h>\n\nint select(int nfds,fd_set *readfds,fd_set *writefds,fd_set *exceptfds,struct timeval *timeout);<\/code><\/pre>\n\n\n\n<p><strong>\u53c2\u6570\u89e3\u91ca: <\/strong><br>\u2022 \u53c2\u6570nfds\u662f\u9700\u8981\u76d1\u89c6\u7684\u6700\u2f24\u7684\u2f42\u4ef6\u63cf\u8ff0\u7b26\u503c+1\uff1b <br>\u2022 rdset,wrset,exset\u5206\u522b\u5bf9\u5e94\u4e8e\u9700\u8981\u68c0\u6d4b\u7684\u53ef\u8bfb\u2f42\u4ef6\u63cf\u8ff0\u7b26\u7684\u96c6\u5408\uff0c\u53ef\u5199\u2f42\u4ef6\u63cf\u8ff0\u7b26\u7684\u96c6 \u5408\u53ca\u5f02\u5e38<br>\u2f42\u4ef6\u63cf\u8ff0\u7b26\u7684\u96c6\u5408; <br>\u2022 \u53c2\u6570timeout\u4e3a\u7ed3\u6784timeval\uff0c\u2f64\u6765\u8bbe\u7f6eselect()\u7684\u7b49\u5f85\u65f6\u95f4<br><strong>\u53c2\u6570timeout\u53d6\u503c: <\/strong><br>\u2022 NULL\uff1a\u5219\u8868\u2f70select\uff08\uff09\u6ca1\u6709timeout\uff0cselect\u5c06\u2f00\u76f4\u88ab\u963b\u585e\uff0c\u76f4\u5230\u67d0\u4e2a\u2f42\u4ef6\u63cf\u8ff0\u7b26\u4e0a\u53d1\u2f63\u4e86\u4e8b\u4ef6; <br>\u2022 0\uff1a\u4ec5\u68c0\u6d4b\u63cf\u8ff0\u7b26\u96c6\u5408\u7684\u72b6\u6001\uff0c\u7136\u540e\u2f74\u5373\u8fd4\u56de\uff0c\u5e76\u4e0d\u7b49\u5f85\u5916\u90e8\u4e8b\u4ef6\u7684\u53d1\u2f63\u3002 <br>\u2022 \u7279\u5b9a\u7684\u65f6\u95f4\u503c\uff1a\u5982\u679c\u5728\u6307\u5b9a\u7684\u65f6\u95f4\u6bb5\u2fa5\u6ca1\u6709\u4e8b\u4ef6\u53d1\u2f63\uff0cselect\u5c06\u8d85\u65f6\u8fd4\u56de\u3002<\/p>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p><strong>\u8f85\u52a9\u5b8f\uff1a<\/strong><\/p>\n\n\n\n<p>FD_ZERO(fd_set *set); \/\/ \u6e05\u7a7a\u96c6\u5408<br>FD_SET(int fd, fd_set *set); \/\/ \u5c06 fd \u52a0\u5165\u96c6\u5408<br>FD_CLR(int fd, fd_set *set); \/\/ \u5c06 fd \u4ece\u96c6\u5408\u4e2d\u79fb\u9664<br>FD_ISSET(int fd, fd_set *set); \/\/ \u5224\u65ad fd \u662f\u5426\u5728\u96c6\u5408\u4e2d<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p>\u5728\u4f20\u7edf\u7684\u963b\u585e I\/O \u6a21\u578b\u4e2d\uff0c\u6bcf\u4e2a\u8fde\u63a5\u9700\u8981\u4e00\u4e2a\u7ebf\u7a0b\u6216\u8fdb\u7a0b\u6765\u5904\u7406\u3002\u5f53\u8fde\u63a5\u6570\u589e\u52a0\u65f6\uff0c\u7ebf\u7a0b\u5207\u6362\u548c\u5185\u5b58\u5f00\u9500\u4f1a\u8fc5\u901f\u81a8\u80c0\u3002<\/p>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p><code>select<\/code> \u7684\u5f15\u5165\u89e3\u51b3\u4e86\u8fd9\u4e2a\u95ee\u9898\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5355\u7ebf\u7a0b\u5904\u7406\u591a\u4e2a\u8fde\u63a5\uff1b<\/li>\n\n\n\n<li>\u963b\u585e\u7b49\u5f85\uff0c\u4e0d\u5360\u7528 CPU\uff1b<\/li>\n\n\n\n<li>\u8de8\u5e73\u53f0\u652f\u6301\u597d\uff0c\u9002\u7528\u4e8e\u5c0f\u578b\u670d\u52a1\u6216\u6559\u5b66\u573a\u666f\u3002<\/li>\n<\/ul>\n<\/div>\n<\/div>\n\n\n\n<p><strong>select\u6267\u2f8f\u8fc7\u7a0b\uff1a<\/strong><\/p>\n\n\n\n<p>fd_set\u7684\u672c\u8d28\u662f\u4e00\u4e2a\u6574\u6570\u6570\u7ec4\uff0c\u66f4\u51c6\u786e\u7684\u6765\u8bf4\u662f\u4e00\u4e2a\u4f4d\u56fe\uff0c\u53d6fd_set\u2ed3\u5ea6\u4e3a1\u5b57\u8282\uff0cfd_set\u4e2d\u7684\u6bcf\u2f00bit\u53ef\u4ee5\u5bf9\u5e94\u2f00\u4e2a\u2f42\u4ef6\u63cf\u8ff0\u7b26fd\u3002\u52191\u5b57\u8282\u2ed3\u7684fd_set\u6700\u2f24\u53ef\u4ee5\u5bf9\u5e948\u4e2afd.<\/p>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p>\uff081\uff09\u6267\u2f8ffd_set set; FD_ZERO(&amp;set);\u5219set\u2f64\u4f4d\u8868\u2f70\u662f0000,0000\u3002 <\/p>\n\n\n\n<p>\uff082\uff09\u82e5fd\uff1d5,\u6267\u2f8fFD_SET(fd,&amp;set);\u540eset\u53d8\u4e3a0001,0000(\u7b2c5\u4f4d\u7f6e\u4e3a1) <\/p>\n\n\n\n<p>\uff083\uff09\u82e5\u518d\u52a0\u2f0afd\uff1d2\uff0cfd=1,\u5219set\u53d8\u4e3a0001,0011 <\/p>\n\n\n\n<p>\uff084\uff09\u6267\u2f8fselect(6,&amp;set,0,0,0)\u963b\u585e\u7b49\u5f85 <\/p>\n\n\n\n<p>\uff085\uff09\u82e5fd=1,fd=2\u4e0a\u90fd\u53d1\u2f63\u53ef\u8bfb\u4e8b\u4ef6\uff0c\u5219select\u8fd4\u56de\uff0c\u6b64\u65f6set\u53d8\u4e3a0000,0011\u3002\u6ce8\u610f\uff1a\u6ca1\u6709\u4e8b\u4ef6\u53d1\u2f63\u7684fd=5\u88ab\u6e05\u7a7a\u3002<\/p>\n<\/div>\n\n\n\n<p><strong>socket\u5c31\u7eea\u6761\u4ef6<\/strong><\/p>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p>\u8bfb\u5c31\u7eea:<\/p>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p>socket\u5185\u6838\u4e2d, \u63a5\u6536\u7f13\u51b2\u533a\u4e2d\u7684\u5b57\u8282\u6570, \u2f24\u4e8e\u7b49\u4e8e\u4f4e\u2f54\u4f4d\u6807\u8bb0SO_RCVLOWAT. \u6b64\u65f6\u53ef\u4ee5\u2f46\u963b\u585e\u7684\u8bfb\u8be5\u2f42\u4ef6\u63cf\u8ff0\u7b26, \u5e76\u4e14\u8fd4\u56de\u503c\u2f24\u4e8e0; <\/p>\n\n\n\n<p> socket TCP\u901a\u4fe1\u4e2d, \u5bf9\u7aef\u5173\u95ed\u8fde\u63a5, \u6b64\u65f6\u5bf9\u8be5socket\u8bfb, \u5219\u8fd4\u56de0; <\/p>\n\n\n\n<p>\u76d1\u542c\u7684socket\u4e0a\u6709\u65b0\u7684\u8fde\u63a5\u8bf7\u6c42;<\/p>\n\n\n\n<p>socket\u4e0a\u6709\u672a\u5904\u7406\u7684\u9519\u8bef;<\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p>\u5199\u5c31\u7eea:<\/p>\n\n\n\n<p>socket\u5185\u6838\u4e2d, \u53d1\u9001\u7f13\u51b2\u533a\u4e2d\u7684\u53ef\u2f64\u5b57\u8282\u6570(\u53d1\u9001\u7f13\u51b2\u533a\u7684\u7a7a\u95f2\u4f4d\u7f6e\u2f24\u2f29), \u2f24\u4e8e\u7b49\u4e8e\u4f4e\u2f54\u4f4d\u6807SO_SNDLOWAT, \u6b64\u65f6\u53ef\u4ee5\u2f46\u963b\u585e\u7684\u5199, \u5e76\u4e14\u8fd4\u56de\u503c\u2f24\u4e8e0; <\/p>\n\n\n\n<p>socket\u7684\u5199\u64cd\u4f5c\u88ab\u5173\u95ed(close\u6216\u8005shutdown). \u5bf9\u2f00\u4e2a\u5199\u64cd\u4f5c\u88ab\u5173\u95ed\u7684socket\u8fdb\u2f8f\u5199\u64cd\u4f5c, \u4f1a\u89e6\u53d1SIGPIPE\u4fe1\u53f7; <\/p>\n\n\n\n<p>socket\u4f7f\u2f64\u2fae\u963b\u585econnect\u8fde\u63a5\u6210\u529f\u6216\u5931\u8d25\u4e4b\u540e;<\/p>\n\n\n\n<p> socket\u4e0a\u6709\u672a\u8bfb\u53d6\u7684\u9519\u8bef;<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p><strong>select\u7684\u7279\u70b9:<\/strong><\/p>\n\n\n\n<p><br>1.\u53ef\u76d1\u63a7\u7684\u2f42\u4ef6\u63cf\u8ff0\u7b26\u4e2a\u6570\u53d6\u51b3\u4e8esizeof(fd_set)\u7684\u503c. \u6211\u8fd9\u8fb9\u670d\u52a1\u5668\u4e0asizeof(fd_set)\uff1d512\uff0c\u6bcfbit\u8868\u2f70\u2f00\u4e2a\u2f42\u4ef6\u63cf\u8ff0\u7b26\uff0c\u5219\u6211\u670d\u52a1\u5668\u4e0a\u2f40\u6301\u7684\u6700\u2f24\u2f42\u4ef6\u63cf\u8ff0\u7b26\u662f512*8=4096.<\/p>\n\n\n\n<p> 2.\u5c06fd\u52a0\u2f0aselect\u76d1\u63a7\u96c6\u7684\u540c\u65f6\uff0c\u8fd8\u8981\u518d\u4f7f\u2f64\u2f00\u4e2a\u6570\u636e\u7ed3\u6784array\u4fdd\u5b58\u653e\u5230select\u76d1\u63a7\u96c6\u4e2d\u7684fd\uff0c \u25e6 \u2f00\u662f\u2f64\u4e8e\u518dselect \u8fd4\u56de\u540e\uff0carray\u4f5c\u4e3a\u6e90\u6570\u636e\u548cfd_set\u8fdb\u2f8fFD_ISSET\u5224\u65ad\u3002 \u25e6 \u2f06\u662fselect\u8fd4\u56de\u540e\u4f1a\u628a\u4ee5\u524d\u52a0\u2f0a\u7684\u4f46\u5e76\u2f46\u4e8b\u4ef6\u53d1\u2f63\u7684fd\u6e05\u7a7a\uff0c\u5219\u6bcf\u6b21\u5f00\u59cbselect\u524d\u90fd\u8981\u91cd\u65b0\u4ecearray\u53d6\u5f97fd\u9010\u2f00\u52a0\u2f0a(FD_ZERO\u6700\u5148)\uff0c\u626b\u63cfarray\u7684\u540c\u65f6\u53d6\u5f97fd\u6700\u2f24\u503cmaxfd\uff0c\u2f64\u4e8eselect\u7684\u7b2c\u2f00\u4e2a\u53c2\u6570\u3002<\/p>\n<\/div>\n\n\n\n<p><strong>select\u7f3a\u70b9 <\/strong><\/p>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p>1.\u6bcf\u6b21\u8c03\u2f64select, \u90fd\u9700\u8981\u2f3f\u52a8\u8bbe\u7f6efd\u96c6\u5408, \u4ece\u63a5\u2f1d\u4f7f\u2f64\u2ec6\u5ea6\u6765\u8bf4\u4e5f\u2fae\u5e38\u4e0d\u4fbf. <\/p>\n\n\n\n<p>2.\u6bcf\u6b21\u8c03\u2f64select\uff0c\u90fd\u9700\u8981\u628afd\u96c6\u5408\u4ece\u2f64\u2f3e\u6001\u62f7\u2ec9\u5230\u5185\u6838\u6001\uff0c\u8fd9\u4e2a\u5f00\u9500\u5728fd\u5f88\u591a\u65f6\u4f1a\u5f88\u2f24 <\/p>\n\n\n\n<p>3.\u540c\u65f6\u6bcf\u6b21\u8c03\u2f64select\u90fd\u9700\u8981\u5728\u5185\u6838\u904d\u5386\u4f20\u9012\u8fdb\u6765\u7684\u6240\u6709fd\uff0c\u8fd9\u4e2a\u5f00\u9500\u5728fd\u5f88\u591a\u65f6\u4e5f\u5f88\u2f24 <\/p>\n\n\n\n<p>4.select\u2f40\u6301\u7684\u2f42\u4ef6\u63cf\u8ff0\u7b26\u6570\u91cf\u592a\u2f29.<\/p>\n<\/div>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u95ee\u9898<\/th><th>\u63cf\u8ff0<\/th><\/tr><\/thead><tbody><tr><td>fd \u6570\u91cf\u9650\u5236<\/td><td>\u9ed8\u8ba4\u6700\u5927\u4e3a 1024\uff08<code>FD_SETSIZE<\/code>\uff09\uff0c\u65e0\u6cd5\u7b80\u5355\u6269\u5c55<\/td><\/tr><tr><td>\u6027\u80fd\u968f fd \u589e\u52a0\u800c\u4e0b\u964d<\/td><td>\u6bcf\u6b21\u8c03\u7528\u90fd\u9700\u8981\u904d\u5386\u6240\u6709 fd\uff0c\u590d\u6742\u5ea6\u4e3a O(n)<\/td><\/tr><tr><td>\u5185\u5b58\u62f7\u8d1d\u5f00\u9500<\/td><td>\u6bcf\u6b21\u8c03\u7528\u90fd\u8981\u5c06 fd \u96c6\u5408\u4ece\u7528\u6237\u6001\u62f7\u8d1d\u5230\u5185\u6838\u6001<\/td><\/tr><tr><td>\u4e0d\u53ef\u4f38\u7f29<\/td><td>\u4e0d\u9002\u5408\u4e07\u7ea7\u5e76\u53d1\u8fde\u63a5\uff0c\u5bb9\u6613\u88ab epoll \u66ff\u4ee3<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><strong>\u4ee3\u7801\u793a\u4f8b<\/strong>\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#pragma once\n#include &lt;iostream>\n#include &lt;sys\/select.h>\n#include \"Common.hpp\"\n#include \"Socket.hpp\"\n#include &lt;vector>\nusing namespace std;\nusing namespace SocketMoudle;\nclass selectServer\n{\nprivate:\n    unique_ptr&lt;Socket> _listenSocket;\n    bool _running = true;\n    const static int size = sizeof(fd_set) * 8;\n    int defaulted = -1;\n    vector&lt;int> fd_array;\n    ;\n\npublic:\n    selectServer(int port) : _listenSocket(make_unique&lt;TcpSocket>(port))\n    {\n        _listenSocket->BuildListenSocket(port);\n        fd_array.resize(size, defaulted);\n    }\n    ~selectServer() {}\n    void start()\n    {\n        while (_running)\n        {\n            \/\/ \u5c06listenSocket\u52a0\u5165\u5230select\u4e2d,\u8ba9select\u5173\u5fc3listenSocket\u7684\u8bfb\u4e8b\u4ef6\n            fd_set readfds;    \/\/ \u8bfb\u6587\u4ef6\u63cf\u8ff0\u7b26\u96c6\n            FD_ZERO(&amp;readfds); \/\/ \u6e05\u7a7a\u6587\u4ef6\u63cf\u8ff0\u7b26\u96c6\n            \/\/ FD_SET(_listenSocket->GetSockFd(),&amp;readfds);\/\/\u5c06listenSocket\u52a0\u5165\u5230\u6587\u4ef6\u63cf\u8ff0\u7b26\u96c6\u4e2d\n            \/\/ \u501f\u52a9\u8f85\u52a9\u6570\u7ec4\u4fdd\u5b58\u670d\u52a1\u5668\u5386\u53f2\u83b7\u53d6\u8fc7\u7684\u6240\u6709fd\n            \/\/ struct timeval timeout={2,0};\/\/\u8bbe\u7f6e\u8d85\u65f6\u65f6\u95f4\u4e3a2\u79d2\n            \/\/ \u6700\u5927\u7684fd\u4e00\u5b9a\u662f\u53d8\u5316\u7684\uff0c\u6bcf\u4e00\u6b21\u90fd\u8981\u91cd\u7f6e\n            fd_array&#91;0] = _listenSocket->GetSockFd();\n            int maxfd = -1;\n            for (int fd : fd_array)\n            {\n                if (fd != defaulted)\n                {\n                    FD_SET(fd, &amp;readfds);\n                    maxfd = max(maxfd, fd);\n                }\n            }\n            int n = select(maxfd + 1, &amp;readfds, nullptr, nullptr, nullptr);\n            switch (n)\n            {\n            case -1:\n                LOG(LogLevel::ERROR) &lt;&lt; \"select error\";\n                break;\n            case 0:\n                LOG(LogLevel::INFO) &lt;&lt; \"select timeout\";\n                break;\n            default:\n                LOG(LogLevel::INFO) &lt;&lt; \"select has event\";\n                Dispatcher(readfds);\n                break;\n            }\n        }\n        _running = false;\n    }\n    void PrintFd()\n    {\n        for (int fd : fd_array)\n        {\n            if (fd != defaulted)\n            {\n                cout &lt;&lt; fd &lt;&lt; endl;\n            }\n        }\n    }\n    void Dispatcher(fd_set &amp;readfds)\n    {\n        \/\/ \u5904\u7406listenSocket\u7684\u8bfb\u4e8b\u4ef6\n        for (int i = 0; i &lt; fd_array.size(); i++)\n        {\n            if (FD_ISSET(fd_array&#91;i], &amp;readfds))\n            {\n                if (fd_array&#91;i] == _listenSocket->GetSockFd())\n                {\n                    \/\/ \u5904\u7406listenSocket\u7684\u8bfb\u4e8b\u4ef6\n                    AcceptNewClient();\n                }\n                else\n                {\n                    \/\/ \u5904\u7406\u5176\u4ed6\u5ba2\u6237\u7aef\n                    Recever(fd_array&#91;i], i);\n                }\n            }\n        }\n    }\n    void AcceptNewClient()\n    {\n\n        NetAddr client;\n        int fd = _listenSocket->Accept(&amp;client); \/\/ \u4e0d\u4f1a\u963b\u585e\uff0c\u5957\u63a5\u5b57\u5df2\u5c31\u7eea\n        if (fd >= 0)\n        {\n            LOG(LogLevel::INFO) &lt;&lt; \"accept a new client:\" + client.stringaddr();\n            \/\/ \u5c06\u65b0\u7684\u5ba2\u6237\u7aef\u52a0\u5165\u5230\u8f85\u52a9\u6570\u7ec4\u4e2d\n            int i = 0;\n            for (; i &lt; fd_array.size(); i++)\n            {\n                if (fd_array&#91;i] == defaulted)\n                {\n                    break;\n                }\n            }\n            if (i == fd_array.size())\n            {\n                LOG(LogLevel::WARNING) &lt;&lt; \"\u8fbe\u5230\u6700\u5927\u8fde\u63a5\u6570\uff0c\u65e0\u6cd5\u63a5\u6536\u65b0\u8fde\u63a5\";\n                close(fd);\n            }\n            else\n            {\n                fd_array&#91;i] = fd;\n            }\n        }\n    }\n    void Recever(int fd, int i)\n    {\n        char buffer&#91;1024];\n        ssize_t n = recv(fd, buffer, sizeof(buffer) - 1, 0);\n        if (n > 0)\n        {\n            buffer&#91;n] = 0;\n            LOG(LogLevel::INFO) &lt;&lt; \"\u6536\u5230\u5ba2\u6237\u7aef\u6570\u636e:\" &lt;&lt; buffer;\n        }\n        else if (n == 0)\n        {\n            LOG(LogLevel::INFO) &lt;&lt; \"\u5ba2\u6237\u7aef\u65ad\u5f00\u8fde\u63a5\";\n            close(fd);\n            \/\/ \u5c06\u5ba2\u6237\u7aeffd\u4ece\u8f85\u52a9\u6570\u7ec4\u4e2d\u79fb\u9664\n            fd_array&#91;i] = defaulted;\n        }\n        else\n        {\n            LOG(LogLevel::ERROR) &lt;&lt; \"\u63a5\u6536\u6570\u636e\u5931\u8d25\";\n        }\n    }\n    void stop()\n    {\n        _running = false;\n    }\n};<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Poll<\/h2>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"514\" height=\"75\" src=\"http:\/\/www.tgwttt.xyz\/wp-content\/uploads\/2025\/11\/image-8.png\" alt=\"\" class=\"wp-image-679\" srcset=\"https:\/\/www.tgwttt.xyz\/wp-content\/uploads\/2025\/11\/image-8.png 514w, https:\/\/www.tgwttt.xyz\/wp-content\/uploads\/2025\/11\/image-8-300x44.png 300w\" sizes=\"auto, (max-width: 514px) 100vw, 514px\" \/><\/figure>\n\n\n\n<p>\u4e0a\u9762\uff0c\u6211\u4eec\u89c1\u8bc6\u4e86\u201c\u4f4d\u56fe + \u6700\u5927 fd\u201d \u7684\u7ecf\u5178\u8bbe\u8ba1\uff0c\u4e5f\u9886\u6559\u4e86 1024 \u4e0a\u9650 \u4e0e O(n) \u904d\u5386 \u5e26\u6765\u7684\u75db\u82e6\u3002<br>\u4eca\u5929\u7684\u4e3b\u89d2 <code>poll<\/code> \u6b63\u662f\u4e3a\u4e86\u62c6\u6389 1024 \u5929\u82b1\u677f\u3001\u7b80\u5316 API \u800c\u8bde\u751f\u7684\u201c\u8fc7\u6e21\u738b\u8005\u201d\u3002\u867d\u7136\u5b83\u4f9d\u65e7\u8eb2\u4e0d\u8fc7 O(n) \u7684\u5bbf\u547d\uff0c\u5374\u662f\u7406\u89e3\u540e\u7eed <code>epoll<\/code> \u7684\u5173\u952e\u8df3\u677f\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u4e00\u3001<code>poll<\/code>&nbsp;\u662f\u4ec0\u4e48\uff1f<\/h2>\n\n\n\n<p><code>poll<\/code> \u4e0e <code>select<\/code> \u540c\u5c5e \u540c\u6b65 I\/O \u591a\u8def\u590d\u7528\uff1a<br>\u4e00\u6b21\u963b\u585e\uff0c\u7b49\u5f85\u591a\u4e2a\u6587\u4ef6\u63cf\u8ff0\u7b26\u5c31\u7eea\uff0c\u8fd4\u56de\u65f6\u544a\u8bc9\u7528\u6237\u201c\u54ea\u4e9b fd \u53d1\u751f\u4e86\u4ec0\u4e48\u4e8b\u4ef6\u201d\u3002<\/p>\n\n\n\n<p>int poll(struct pollfd *fds, nfds_t nfds, int timeout);<\/p>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p>\u6838\u5fc3\u6570\u636e\uff1a<\/p>\n\n\n\n<p>struct pollfd {<br>int fd; \/\/ \u8981\u76d1\u89c6\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26<br>short events; \/\/ \u8f93\u5165\uff1a\u5173\u5fc3\u7684\u4e8b\u4ef6\u63a9\u7801<br>short revents; \/\/ \u8f93\u51fa\uff1a\u5185\u6838\u8fd4\u56de\u7684\u5c31\u7eea\u4e8b\u4ef6<br>};<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p><strong>\u53c2\u6570\u8bf4\u660e<\/strong>\uff1a<\/p>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p>fds\u662f\u2f00\u4e2apoll\u51fd\u6570\u76d1\u542c\u7684\u7ed3\u6784\u5217\u8868. \u6bcf\u2f00\u4e2a\u5143\u7d20\u4e2d, \u5305\u542b\u4e86\u4e09\u90e8\u5206\u5185\u5bb9: \u2f42\u4ef6\u63cf\u8ff0\u7b26, \u76d1\u542c\u7684\u4e8b\u4ef6\u96c6\u5408, \u8fd4\u56de\u7684\u4e8b\u4ef6\u96c6\u5408. <\/p>\n\n\n\n<p>nfds\u8868\u2f70fds\u6570\u7ec4\u7684\u2ed3\u5ea6. <\/p>\n\n\n\n<p>timeout\u8868\u2f70poll\u51fd\u6570\u7684\u8d85\u65f6\u65f6\u95f4, \u5355\u4f4d\u662f\u6beb\u79d2(ms).<\/p>\n<\/div>\n<\/div>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u4e8b\u4ef6<\/th><th>\u8bf4\u660e<\/th><\/tr><\/thead><tbody><tr><td><code>POLLIN<\/code><\/td><td>\u53ef\u8bfb\uff08\u542b\u65b0\u8fde\u63a5\uff09<\/td><\/tr><tr><td><code>POLLOUT<\/code><\/td><td>\u53ef\u5199<\/td><\/tr><tr><td><code>POLLERR<\/code><\/td><td>\u51fa\u9519<\/td><\/tr><tr><td><code>POLLHUP<\/code><\/td><td>\u5bf9\u7aef\u6302\u8d77<\/td><\/tr><tr><td><code>POLLRDHUP<\/code><\/td><td>TCP \u5bf9\u7aef\u5173\u95ed\u5199\uff08Linux 2.6.17+\uff09<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><strong>poll\u7684\u4f18\u70b9<\/strong>\uff1a<\/p>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p>\u4e0d\u540c\u4e8eselect\u4f7f\u2f64\u4e09\u4e2a\u4f4d\u56fe\u6765\u8868\u2f70\u4e09\u4e2afdset\u7684\u2f45\u5f0f\uff0cpoll\u4f7f\u2f64\u2f00\u4e2apollfd\u7684\u6307\u9488\u5b9e\u73b0. <\/p>\n\n\n\n<p> pollfd\u7ed3\u6784\u5305\u542b\u4e86\u8981\u76d1\u89c6\u7684event\u548c\u53d1\u2f63\u7684event\uff0c\u4e0d\u518d\u4f7f\u2f64select\u201c\u53c2\u6570-\u503c\u201d\u4f20\u9012\u7684\u2f45\u5f0f. \u63a5\u2f1d\u4f7f\u2f64\u2f50select\u2f45\u4fbf. <\/p>\n\n\n\n<p>poll\u5e76\u6ca1\u6709\u6700\u2f24\u6570\u91cf\u9650\u5236 (\u4f46\u662f\u6570\u91cf\u8fc7\u2f24\u540e\u6027\u80fd\u4e5f\u662f\u4f1a\u4e0b\u964d).<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p><strong>poll\u7684\u7f3a\u70b9 <\/strong><\/p>\n\n\n\n<p>poll\u4e2d\u76d1\u542c\u7684\u2f42\u4ef6\u63cf\u8ff0\u7b26\u6570\u2f6c\u589e\u591a\u65f6 <\/p>\n\n\n\n<p>\u548cselect\u51fd\u6570\u2f00\u6837\uff0cpoll\u8fd4\u56de\u540e\uff0c\u9700\u8981\u8f6e\u8be2pollfd\u6765\u83b7\u53d6\u5c31\u7eea\u7684\u63cf\u8ff0\u7b26. <\/p>\n\n\n\n<p> \u6bcf\u6b21\u8c03\u2f64poll\u90fd\u9700\u8981\u628a\u2f24\u91cf\u7684pollfd\u7ed3\u6784\u4ece\u2f64\u2f3e\u6001\u62f7\u2ec9\u5230\u5185\u6838\u4e2d. <\/p>\n\n\n\n<p>\u540c\u65f6\u8fde\u63a5\u7684\u2f24\u91cf\u5ba2\u2f3e\u7aef\u5728\u2f00\u65f6\u523b\u53ef\u80fd\u53ea\u6709\u5f88\u5c11\u7684\u5904\u4e8e\u5c31\u7eea\u72b6\u6001, \u56e0\u6b64\u968f\u7740\u76d1\u89c6\u7684\u63cf\u8ff0\u7b26\u6570\u91cf\u7684\u589e\u2ed3, \u5176\u6548\u7387\u4e5f\u4f1a\u7ebf\u6027\u4e0b\u964d.<\/p>\n<\/div>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>\u4ee3\u7801\u793a\u4f8b<\/strong>\n#pragma once\n#include &lt;iostream>\n#include &lt;sys\/select.h>\n#include \"Common.hpp\"\n#include \"Socket.hpp\"\n#include &lt;vector>\n#include&lt;unistd.h>\n#include&lt;sys\/poll.h>\nusing namespace std;\nusing namespace SocketMoudle;\nclass pollServer\n{\nprivate:\n    unique_ptr&lt;Socket> _listenSocket;\n    bool _running = true;\n    const int defaulted = -1;\n    static const int size = 4096;\n    struct pollfd pfds&#91;size];\npublic:\n    pollServer(int port) : _listenSocket(make_unique&lt;TcpSocket>(port))\n    {\n        _listenSocket->BuildListenSocket(port);\n        \/\/ \u521d\u59cb\u5316\u8f85\u52a9\u6570\u7ec4\n        for (int i = 0; i &lt; size; i++)\n        {\n            pfds&#91;i].fd = defaulted;\n            pfds&#91;i].events = 0;\n            pfds&#91;i].revents = 0;\n        }\n        pfds&#91;0].fd = _listenSocket->GetSockFd();\n        pfds&#91;0].events = POLLIN;\n    }\n    ~pollServer() {}\n    void start()\n    {\n        while (_running)\n        {\n            \/\/int timeout=1000; \/\/ \u8d85\u65f6\u65f6\u95f4(MS)\n            int n = poll(pfds, size, -1);\n            switch (n)\n            {\n            case -1:\n                LOG(LogLevel::ERROR) &lt;&lt; \"select error\";\n                break;\n            case 0:\n                LOG(LogLevel::INFO) &lt;&lt; \"select timeout\";\n                break;\n            default:\n                LOG(LogLevel::INFO) &lt;&lt; \"select has event\";\n                Dispatcher(pfds);\n                break;\n            }\n        }\n        _running = false;\n    }\n    void Dispatcher(struct pollfd pfds&#91;])\n    {\n        \/\/ \u5904\u7406listenSocket\u7684\u8bfb\u4e8b\u4ef6\n        for (int i = 0; i &lt; size; i++)\n        {\n            if (pfds&#91;i].revents &amp; POLLIN)\n            {\n                if (pfds&#91;i].fd == _listenSocket->GetSockFd())\n                {\n                    \/\/ \u5904\u7406listenSocket\u7684\u8bfb\u4e8b\u4ef6\n                    AcceptNewClient();\n                }\n                else\n                {\n                    \/\/ \u5904\u7406\u5176\u4ed6\u5ba2\u6237\u7aef\n                    Recever(i);\n                }\n            }\n        }\n    }\n    void AcceptNewClient()\n    {\n\n        NetAddr client;\n        int fd = _listenSocket->Accept(&amp;client); \/\/ \u4e0d\u4f1a\u963b\u585e\uff0c\u5957\u63a5\u5b57\u5df2\u5c31\u7eea\n        if (fd >= 0)\n        {\n            LOG(LogLevel::INFO) &lt;&lt; \"accept a new client:\" + client.stringaddr();\n            \/\/ \u5c06\u65b0\u7684\u5ba2\u6237\u7aef\u52a0\u5165\u5230\u8f85\u52a9\u6570\u7ec4\u4e2d\n            int i = 0;\n            for (; i &lt; size; i++)\n            {\n                if (pfds&#91;i].fd == defaulted)\n                {\n                    break;\n                }\n            }\n            if (i == size)\n            {\n                LOG(LogLevel::WARNING) &lt;&lt; \"\u8fbe\u5230\u6700\u5927\u8fde\u63a5\u6570\uff0c\u65e0\u6cd5\u63a5\u6536\u65b0\u8fde\u63a5\";\n                 \/\/\u5982\u679c\u662f\u6307\u9488\u6269\u5bb9\u5373\u53ef\uff0c\u8fd9\u91cc\u4e0d\u505a\u5904\u7406\n                close(fd);\n            }\n            else\n            {\n                pfds&#91;i].fd = fd;\n                pfds&#91;i].events = POLLIN;\n                pfds&#91;i].revents = 0;\n            }\n        }\n    }\n    void Recever(int i)\n    {\n        char buffer&#91;1024];\n        ssize_t n = recv(pfds&#91;i].fd, buffer, sizeof(buffer) - 1, 0);\n        if (n > 0)\n        {\n            buffer&#91;n] = 0;\n            cout&lt;&lt; \"\u6536\u5230\u5ba2\u6237\u7aef\u6570\u636e:\" &lt;&lt; buffer;\n        }\n        else if (n == 0)\n        {\n            LOG(LogLevel::INFO) &lt;&lt; \"\u5ba2\u6237\u7aef\u65ad\u5f00\u8fde\u63a5\";\n            close(pfds&#91;i].fd);\n            \/\/ \u5c06\u5ba2\u6237\u7aeffd\u4ece\u8f85\u52a9\u6570\u7ec4\u4e2d\u79fb\u9664\n            pfds&#91;i].fd = defaulted;\n            pfds&#91;i].events = 0;\n            pfds&#91;i].revents = 0;\n        }\n        else\n        {\n            LOG(LogLevel::ERROR) &lt;&lt; \"\u63a5\u6536\u6570\u636e\u5931\u8d25\";\n            \n        }\n    }\n    void stop()\n    {\n        _running = false;\n    }\n};<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Epoll<\/strong><\/h2>\n\n\n\n<p><strong>\u521d\u8bc6epoll<\/strong><\/p>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p>\u524d\u9762\u6211\u4eec\u5206\u522b\u62c6\u89e3\u4e86 <code>select<\/code> \u4e0e <code>poll<\/code>\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>select<\/code> \u7528 \u4f4d\u56fe\uff0c\u4e0a\u9650 1024\uff0cO(\u6700\u9ad8 fd)\uff1b<\/li>\n\n\n\n<li><code>poll<\/code> \u6362\u6210 \u6570\u7ec4\uff0c\u62c6\u6389 1024\uff0c\u5374\u4ecd\u9003\u4e0d\u6389 O(n) \u8f6e\u8be2\u3002<\/li>\n<\/ul>\n\n\n\n<p>\u5f53 C10K \u2192 C100K \u2192 C1000K \u65f6\uff0cCPU \u65f6\u95f4\u7edd\u5927\u90e8\u5206\u6d6a\u8d39\u5728 \u201c\u904d\u5386\u4e00\u5806\u672a\u5c31\u7eea\u7684 fd\u201d \u4e0a\u3002<br>epoll \u7684\u51fa\u73b0\uff0c\u5c31\u662f\u4e3a\u4e86\u628a \u201c\u904d\u5386\u201d \u53d8\u6210 \u201c\u56de\u8c03\u201d\uff0c\u8ba9\u590d\u6742\u5ea6\u4ece O(n) \u964d\u5230 <strong class=\"\">O(1)<\/strong>\u3002<\/p>\n<\/div>\n\n\n\n<p>int epoll_create1(int flags); \/\/ \u5efa\u4e00\u68f5\u7ea2\u9ed1\u6811<br>int epoll_ctl(int epfd, int op, int fd, struct epoll_event *ev);<br>int epoll_wait(int epfd, struct epoll_event *evs, int maxevents, int timeout);<\/p>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p> \u5b83\u4e0d\u540c\u4e8eselect()\u662f\u5728\u76d1\u542c\u4e8b\u4ef6\u65f6\u544a\u8bc9\u5185\u6838\u8981\u76d1\u542c\u4ec0\u4e48\u7c7b\u578b\u7684\u4e8b\u4ef6, \u2f7d\u662f\u5728\u8fd9\u2fa5\u5148\u6ce8\u518c\u8981\u76d1\u542c\u7684\u4e8b\u4ef6\u7c7b\u578b. <\/p>\n\n\n\n<p> \u7b2c\u2f00\u4e2a\u53c2\u6570\u662fepoll_create()\u7684\u8fd4\u56de\u503c(epoll\u7684\u53e5\u67c4). <\/p>\n\n\n\n<p> \u7b2c\u2f06\u4e2a\u53c2\u6570\u8868\u2f70\u52a8\u4f5c\uff0c\u2f64\u4e09\u4e2a\u5b8f\u6765\u8868\u2f70. <\/p>\n\n\n\n<p> \u7b2c\u4e09\u4e2a\u53c2\u6570\u662f\u9700\u8981\u76d1\u542c\u7684fd. <\/p>\n\n\n\n<p> \u7b2c\u56db\u4e2a\u53c2\u6570\u662f\u544a\u8bc9\u5185\u6838\u9700\u8981\u76d1\u542c\u4ec0\u4e48\u4e8b.<\/p>\n<\/div>\n\n\n\n<p>struct epoll_event {<br>__uint32_t events; \/\/ \u4e8b\u4ef6\u63a9\u7801 EPOLLIN | EPOLLOUT \u2026<br>epoll_data_t data; \/\/ \u7528\u6237\u9644\u7740\u6570\u636e<br>};<\/p>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p>\u64cd\u4f5c\u7801op<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>EPOLL_CTL_ADD<\/code>\uff1a\u63d2\u5165\u8282\u70b9<\/li>\n\n\n\n<li><code>EPOLL_CTL_MOD<\/code>\uff1a\u4fee\u6539\u4e8b\u4ef6<\/li>\n\n\n\n<li><code>EPOLL_CTL_DEL<\/code>\uff1a\u5220\u9664\u8282\u70b9<\/li>\n<\/ul>\n<\/div>\n\n\n\n<p><strong>epoll\u2f2f\u4f5c\u539f\u7406<\/strong><br><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"872\" height=\"738\" src=\"http:\/\/www.tgwttt.xyz\/wp-content\/uploads\/2025\/11\/image-9.png\" alt=\"\" class=\"wp-image-680\" srcset=\"https:\/\/www.tgwttt.xyz\/wp-content\/uploads\/2025\/11\/image-9.png 872w, https:\/\/www.tgwttt.xyz\/wp-content\/uploads\/2025\/11\/image-9-300x254.png 300w, https:\/\/www.tgwttt.xyz\/wp-content\/uploads\/2025\/11\/image-9-768x650.png 768w\" sizes=\"auto, (max-width: 872px) 100vw, 872px\" \/><\/figure>\n\n\n\n<p>epoll\u6a21\u578b\u5728\u5e95\u5c42\u6709\u8fd9\u6837\u4e00\u9897<strong>\u7ea2\u9ed1\u6811<\/strong>\uff0c\u50a8\u5b58\u4e86\u6587\u4ef6\u63cf\u8ff0\u7b26\u4fe1\u606f\u548c\u6587\u4ef6\u9700\u8981\u5173\u5fc3\u7684\u4e8b\u4ef6\u4fe1\u606f\uff0c\u6b64\u5916\u8fd8\u7ef4\u62a4\u4e86\u4e00\u4e2a<strong>\u5c31\u7eea\u961f\u5217<\/strong>\uff0c\u5185\u6838\u4f1a\u5c06\u5df2\u5c31\u7eea\u7684\u6587\u4ef6\u4fe1\u606f\u6dfb\u52a0\u5230\u5c31\u7eea\u961f\u5217\u4e2d\u3002\u5176\u6838\u5fc3\u539f\u7406\u662f\u901a\u8fc7\u5185\u6838\u4e0e\u7528\u6237\u7a7a\u95f4\u5171\u4eab\u5185\u5b58\uff0c\u5728\u5185\u6838\u4e2d\u7ef4\u62a4\u4e00\u4e2a\u4e8b\u4ef6\u8868\uff0c\u5f53\u6709\u6587\u4ef6\u63cf\u8ff0\u7b26\u5c31\u7eea\u65f6\uff0c\u5185\u6838\u4f1a\u5c06\u5176\u52a0\u5165\u5c31\u7eea\u961f\u5217\uff0c\u7528\u6237\u7a7a\u95f4\u901a\u8fc7\u00a0epoll_wait\u00a0\u51fd\u6570\u83b7\u53d6\u5c31\u7eea\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26\uff0c\u800c\u65e0\u9700\u50cf\u00a0select\u00a0\u548c\u00a0poll\u00a0\u90a3\u6837\u904d\u5386\u6574\u4e2a\u6587\u4ef6\u63cf\u8ff0\u7b26\u96c6\u5408\u3002\u00a0\u5728\u00a0I\/O\u00a0\u591a\u8def\u590d\u7528\u673a\u5236\u4e2d\uff0cselect\u00a0\u548c\u00a0poll\u00a0\u662f\u00a0epoll\u00a0\u7684\u00a0\u201c\u524d\u8f88\u201d\uff0c\u4f46\u5b83\u4eec\u5b58\u5728\u4e00\u4e9b\u660e\u663e\u7684\u4e0d\u8db3\uff0c\u800c\u00a0epoll\u00a0\u6b63\u662f\u4e3a\u514b\u670d\u8fd9\u4e9b\u4e0d\u8db3\u800c\u51fa\u73b0\u7684\u3002<\/p>\n\n\n\n<p><strong>\u89e6\u53d1\u6a21\u5f0f<\/strong><\/p>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p><strong>\u2f54\u5e73\u89e6\u53d1Level Triggered \u2f2f\u4f5c\u6a21\u5f0f <\/strong><\/p>\n\n\n\n<p>epoll\u9ed8\u8ba4\u72b6\u6001\u4e0b\u5c31\u662fLT\u2f2f\u4f5c\u6a21\u5f0f. <\/p>\n\n\n\n<p> \u5f53epoll\u68c0\u6d4b\u5230socket\u4e0a\u4e8b\u4ef6\u5c31\u7eea\u7684\u65f6\u5019, \u53ef\u4ee5\u4e0d\u2f74\u523b\u8fdb\u2f8f\u5904\u7406. \u6216\u8005\u53ea\u5904\u7406\u2f00\u90e8\u5206. \u2022<\/p>\n\n\n\n<p>\u5982\u679c\u7f13\u51b2\u533a\u4e2d\u67092k\u6570\u636e\uff0c\u53ea\u8bfb\u4e861K\u6570\u636e, \u7f13\u51b2\u533a\u4e2d\u8fd8\u52691K\u6570\u636e, \u5728\u7b2c\u2f06\u6b21\u8c03\u2f64 epoll_wait \u65f6, epoll_wait \u4ecd\u7136\u4f1a\u2f74\u523b\u8fd4\u56de\u5e76\u901a\u77e5socket\u8bfb\u4e8b\u4ef6\u5c31\u7eea. <\/p>\n\n\n\n<p>\u76f4\u5230\u7f13\u51b2\u533a\u4e0a\u6240\u6709\u7684\u6570\u636e\u90fd\u88ab\u5904\u7406\u5b8c, epoll_wait \u624d\u4f1a\u2f74\u523b\u8fd4\u56de. <\/p>\n<\/div>\n\n\n\n<p>\u2f40\u6301\u963b\u585e\u8bfb\u5199\u548c\u2fae\u963b\u585e\u8bfb\u5199<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p><strong>\u8fb9\u7f18\u89e6\u53d1Edge Triggered\u2f2f\u4f5c\u6a21\u5f0f <\/strong><\/p>\n\n\n\n<p>\u5982\u679c\u6211\u4eec\u5728\u7b2c1\u6b65\u5c06socket\u6dfb\u52a0\u5230epoll\u63cf\u8ff0\u7b26\u7684\u65f6\u5019\u4f7f\u2f64\u4e86EPOLLET\u6807\u5fd7, epoll\u8fdb\u2f0aET\u2f2f\u4f5c\u6a21\u5f0f. <\/p>\n\n\n\n<p>\u5f53epoll\u68c0\u6d4b\u5230socket\u4e0a\u4e8b\u4ef6\u5c31\u7eea\u65f6, \u5fc5\u987b\u2f74\u523b\u5904\u7406. <\/p>\n\n\n\n<p>\u5982\u4e0a\u2faf\u7684\u4f8b\u2f26, \u867d\u7136\u53ea\u8bfb\u4e861K\u7684\u6570\u636e, \u7f13\u51b2\u533a\u8fd8\u52691K\u7684\u6570\u636e, \u5728\u7b2c\u2f06\u6b21\u8c03\u2f64 epoll_wait \u7684\u65f6\u5019, epoll_wait \u4e0d\u4f1a\u518d\u8fd4\u56de\u4e86. <\/p>\n\n\n\n<p> \u4e5f\u5c31\u662f\u8bf4, ET\u6a21\u5f0f\u4e0b, \u2f42\u4ef6\u63cf\u8ff0\u7b26\u4e0a\u7684\u4e8b\u4ef6\u5c31\u7eea\u540e, \u53ea\u6709\u2f00\u6b21\u5904\u7406\u673a\u4f1a. <\/p>\n\n\n\n<p> ET\u7684\u6027\u80fd\u2f50LT\u6027\u80fd\u66f4\u2fbc( epoll_wait \u8fd4\u56de\u7684\u6b21\u6570\u5c11\u4e86\u5f88\u591a). Nginx\u9ed8\u8ba4\u91c7\u2f64ET\u6a21\u5f0f\u4f7f\u2f64epoll. <\/p>\n\n\n\n<p>\u53ea\u2f40\u6301\u2fae\u963b\u585e\u7684\u8bfb\u5199select\u548cpoll\u5176\u5b9e\u4e5f\u662f\u2f2f\u4f5c\u5728LT\u6a21\u5f0f\u4e0b. epoll\u65e2\u53ef\u4ee5\u2f40\u6301LT, \u4e5f\u53ef\u4ee5\u2f40\u6301ET.<\/p>\n<\/div>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u6a21\u5f0f<\/th><th>\u884c\u4e3a<\/th><th>\u8bfb\u4e8b\u4ef6\u4e3e\u4f8b<\/th><\/tr><\/thead><tbody><tr><td><strong>LT<\/strong>\uff08Level Trigger\uff0c\u6c34\u5e73\u89e6\u53d1\uff09<\/td><td>\u53ea\u8981 fd \u5904\u4e8e\u5c31\u7eea\u72b6\u6001\uff0c\u6bcf\u6b21 <code>epoll_wait<\/code> \u90fd\u8fd4\u56de<\/td><td>\u7f13\u51b2\u533a\u6709\u6570\u636e\u5c31\u901a\u77e5<\/td><\/tr><tr><td><strong>ET<\/strong>\uff08Edge Trigger\uff0c\u8fb9\u7f18\u89e6\u53d1\uff09<\/td><td>\u72b6\u6001\u53d8\u5316\u77ac\u95f4 \u53ea\u901a\u77e5\u4e00\u6b21<\/td><td>\u7f13\u51b2\u533a\u4ece\u7a7a\u2192\u6709\u901a\u77e5\u4e00\u6b21\uff0c\u540e\u7eed\u4e0d\u518d\u63d0\u9192<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>ET \u6a21\u5f0f\u80fd\u663e\u8457\u51cf\u5c11\u4e8b\u4ef6\u901a\u77e5\u6b21\u6570\uff0c\u4f46\u5fc5\u987b \u4e00\u6b21\u6027\u628a\u6570\u636e\u8bfb\u7a7a\uff0c\u5426\u5219\u6570\u636e\u4f1a\u5931\u6548<\/p>\n\n\n\n<p><strong>epoll\u7684\u4f18\u70b9(\u548c select \u7684\u7f3a\u70b9\u5bf9\u5e94) <\/strong><\/p>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p>1.\u63a5\u2f1d\u4f7f\u2f64\u2f45\u4fbf: \u867d\u7136\u62c6\u5206\u6210\u4e86\u4e09\u4e2a\u51fd\u6570, \u4f46\u662f\u53cd\u2f7d\u4f7f\u2f64\u8d77\u6765\u66f4\u2f45\u4fbf\u2fbc\u6548. \u4e0d\u9700\u8981\u6bcf\u6b21\u5faa\u73af\u90fd\u8bbe\u7f6e\u5173\u6ce8\u7684\u2f42\u4ef6\u63cf\u8ff0\u7b26, \u4e5f\u505a\u5230\u4e86\u8f93\u2f0a\u8f93\u51fa\u53c2\u6570\u5206\u79bb\u5f00 <\/p>\n\n\n\n<p>2.\u6570\u636e\u62f7\u2ec9\u8f7b\u91cf: \u53ea\u5728\u5408\u9002\u7684\u65f6\u5019\u8c03\u2f64 EPOLL_CTL_ADD \u5c06\u2f42\u4ef6\u63cf\u8ff0\u7b26\u7ed3\u6784\u62f7\u2ec9\u5230\u5185\u6838\u4e2d, \u8fd9\u4e2a\u64cd\u4f5c\u5e76\u4e0d\u9891\u7e41(\u2f7dselect\/poll\u90fd\u662f\u6bcf\u6b21\u5faa\u73af\u90fd\u8981\u8fdb\u2f8f\u62f7\u2ec9) <\/p>\n\n\n\n<p>3.\u4e8b\u4ef6\u56de\u8c03\u673a\u5236: \u907f\u514d\u4f7f\u2f64\u904d\u5386, \u2f7d\u662f\u4f7f\u2f64\u56de\u8c03\u51fd\u6570\u7684\u2f45\u5f0f, \u5c06\u5c31\u7eea\u7684\u2f42\u4ef6\u63cf\u8ff0\u7b26\u7ed3\u6784\u52a0\u2f0a\u5230\u5c31\u7eea\u961f\u5217\u4e2d, epoll_wait \u8fd4\u56de\u76f4\u63a5\u8bbf\u95ee\u5c31\u7eea\u961f\u5217\u5c31\u77e5\u9053\u54ea\u4e9b\u2f42\u4ef6\u63cf\u8ff0\u7b26\u5c31\u7eea. \u8fd9\u4e2a\u64cd\u4f5c\u65f6\u95f4\u590d\u6742\u5ea6O(1). \u5373\u4f7f\u2f42\u4ef6\u63cf\u8ff0\u7b26\u6570\u2f6c\u5f88\u591a, \u6548\u7387\u4e5f\u4e0d\u4f1a\u53d7\u5230\u5f71\u54cd. \u2022 \u6ca1\u6709\u6570\u91cf\u9650\u5236: \u2f42\u4ef6\u63cf\u8ff0\u7b26\u6570\u2f6c\u2f46\u4e0a\u9650.<\/p>\n\n\n\n<p>\u5bf9\u6bd4<\/p>\n<\/div>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u7ef4\u5ea6<\/th><th>select<\/th><th>poll<\/th><th>epoll<\/th><\/tr><\/thead><tbody><tr><td>\u6570\u636e\u7ed3\u6784<\/td><td>\u4f4d\u56fe <code>fd_set<\/code><\/td><td>\u6570\u7ec4 <code>struct pollfd<\/code><\/td><td>\u7ea2\u9ed1\u6811 + \u5c31\u7eea\u94fe\u8868<\/td><\/tr><tr><td>\u6700\u5927 fd \u6570<\/td><td>1024\uff08FD_SETSIZE\uff09<\/td><td>\u65e0\u786c\u4e0a\u9650<\/td><td>\u65e0\u786c\u4e0a\u9650<\/td><\/tr><tr><td>\u7528\u6237\u2192\u5185\u6838<\/td><td>\u6bcf\u6b21\u6574\u5305\u62f7\u8d1d<\/td><td>\u6bcf\u6b21\u6574\u5305\u62f7\u8d1d<\/td><td>\u4e00\u6b21 <code>epoll_ctl<\/code> \u6ce8\u518c\uff0c\u6c38\u4e45\u6709\u6548<\/td><\/tr><tr><td>\u5185\u6838\u2192\u7528\u6237<\/td><td>\u6574\u5305\u62f7\u56de + \u6e05\u96f6<\/td><td>\u6574\u5305\u62f7\u56de<\/td><td>\u53ea\u62f7\u5c31\u7eea\u4e8b\u4ef6<\/td><\/tr><tr><td>\u67e5\u627e\u65b9\u5f0f<\/td><td>\u8f6e\u8be2 0~nfds-1<\/td><td>\u8f6e\u8be2\u6574\u4e2a\u6570\u7ec4<\/td><td>\u56de\u8c03\u76f4\u63a5\u94fe\u5165\u5c31\u7eea\u961f\u5217<\/td><\/tr><tr><td>\u65f6\u95f4\u590d\u6742\u5ea6<\/td><td>O(\u6700\u9ad8 fd)<\/td><td>O(\u6570\u7ec4\u957f\u5ea6)<\/td><td>O(1) \u5c31\u7eea\u6570<\/td><\/tr><tr><td>\u89e6\u53d1\u6a21\u5f0f<\/td><td>\u53ea\u6709 LT<\/td><td>\u53ea\u6709 LT<\/td><td><strong>LT + ET<\/strong><\/td><\/tr><tr><td>\u8de8\u5e73\u53f0<\/td><td>_POSIX_C_SOURCE 2001<\/td><td>\u540c\u5de6<\/td><td><strong>Linux only<\/strong><\/td><\/tr><tr><td>\u4ee3\u7801\u590d\u6742\u5ea6<\/td><td>\u5b8f\u64cd\u4f5c\u5570\u55e6<\/td><td>\u6570\u7ec4\u76f4\u89c2<\/td><td>\u9700\u8981\u5904\u7406 ET \u975e\u963b\u585e<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><strong>\u4ee3\u7801\u4e3e\u4f8b\uff1a<\/strong><\/p>\n\n\n\n<p><strong>ET+\u975e\u963b\u585e<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ echo_server_et.c\n#define _GNU_SOURCE\n#include &lt;stdio.h>\n#include &lt;stdlib.h>\n#include &lt;string.h>\n#include &lt;unistd.h>\n#include &lt;errno.h>\n#include &lt;fcntl.h>\n#include &lt;sys\/socket.h>\n#include &lt;sys\/epoll.h>\n#include &lt;netinet\/in.h>\n#include &lt;arpa\/inet.h>\n\n#define PORT 7777\n#define MAX_EVENTS 1024\n#define BUF_SIZE 4096\n\nstatic int set_nonblock(int fd) {\n    return fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);\n}\n\nint create_listener() {\n    int fd = socket(AF_INET, SOCK_STREAM, 0);\n    int opt = 1;\n    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &amp;opt, sizeof(opt));\n    struct sockaddr_in addr = {\n        .sin_family = AF_INET,\n        .sin_port   = htons(PORT),\n        .sin_addr.s_addr = htonl(INADDR_ANY)\n    };\n    bind(fd, (struct sockaddr*)&amp;addr, sizeof(addr));\n    listen(fd, 128);\n    set_nonblock(fd);\n    return fd;\n}\n\nvoid do_read(int epfd, int fd);\n\nvoid do_accept(int epfd, int lfd) {\n    while (1) {\n        struct sockaddr_in cli;\n        socklen_t len = sizeof(cli);\n        int conn = accept(lfd, (struct sockaddr*)&amp;cli, &amp;len);\n        if (conn &lt; 0) {\n            if (errno == EAGAIN || errno == EWOULDBLOCK) break;\n            perror(\"accept\");\n            continue;\n        }\n        set_nonblock(conn);\n        struct epoll_event ev = { .events = EPOLLIN | EPOLLET, .data.fd = conn };\n        epoll_ctl(epfd, EPOLL_CTL_ADD, conn, &amp;ev);\n        printf(\"new conn %d\\n\", conn);\n    }\n}\n\nvoid do_read(int epfd, int fd) {\n    char buf&#91;BUF_SIZE];\n    while (1) {\n        ssize_t n = read(fd, buf, sizeof(buf));\n        if (n > 0) {\n            write(fd, buf, n);          \/\/ \u56de\u663e\n        } else if (n == 0) {            \/\/ \u5bf9\u7aef FIN\n            close(fd);\n            epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);\n            break;\n        } else {\n            if (errno == EAGAIN || errno == EWOULDBLOCK)\n                break;                  \/\/ \u8bfb\u7a7a\uff0cET \u9700\u8981\u518d\u6b21\u7b49\u5f85\n            perror(\"read\");\n            close(fd);\n            epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);\n            break;\n        }\n    }\n}\n\nint main() {\n    int lfd = create_listener();\n    int epfd = epoll_create1(0);\n    struct epoll_event ev = { .events = EPOLLIN | EPOLLET, .data.fd = lfd };\n    epoll_ctl(epfd, EPOLL_CTL_ADD, lfd, &amp;ev);\n\n    struct epoll_event evs&#91;MAX_EVENTS];\n    while (1) {\n        int n = epoll_wait(epfd, evs, MAX_EVENTS, -1);\n        for (int i = 0; i &lt; n; ++i) {\n            int fd = evs&#91;i].data.fd;\n            if (fd == lfd) {\n                do_accept(epfd, lfd);\n            } else if (evs&#91;i].events &amp; EPOLLIN) {\n                do_read(epfd, fd);\n            } else if (evs&#91;i].events &amp; (EPOLLERR | EPOLLHUP)) {\n                close(fd);\n                epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);\n            }\n        }\n    }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">\u4eca\u5929\u7684\u66f4\u65b0\u5c31\u5230\u8fd9\u91cc\u5566\uff0c\u5982\u6709\u9519\u8bef\u6b22\u8fce\u8bc4\u8bba\u533a\u6307\u51fa\uff01\uff01\uff01<\/h2>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>select and poll\u4ee3\u7801\u793a\u4f8b\uff1ahttps:\/\/gitee.com\/tgwTTT\/linux-lear&#8230;<\/p>\n","protected":false},"author":1,"featured_media":678,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"categories":[4,5,7],"tags":[],"class_list":["post-677","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c","category-linux","category-7"],"_links":{"self":[{"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=\/wp\/v2\/posts\/677","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=677"}],"version-history":[{"count":1,"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=\/wp\/v2\/posts\/677\/revisions"}],"predecessor-version":[{"id":681,"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=\/wp\/v2\/posts\/677\/revisions\/681"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=\/wp\/v2\/media\/678"}],"wp:attachment":[{"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=677"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=677"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=677"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}