{"id":509,"date":"2026-05-24T12:18:31","date_gmt":"2026-05-24T04:18:31","guid":{"rendered":"https:\/\/www.garfield-blog.top\/?p=509"},"modified":"2026-05-31T13:48:50","modified_gmt":"2026-05-31T05:48:50","slug":"%e3%80%90linux%e3%80%91%e3%80%90%e6%ba%90%e7%a0%81%e8%a7%a3%e6%9e%90%e3%80%91epoll%e8%bd%af%e4%bb%b6%e6%9e%b6%e6%9e%84%e5%8f%8a%e5%8e%9f%e7%90%86","status":"publish","type":"post","link":"https:\/\/www.garfield-blog.top\/?p=509","title":{"rendered":"\u3010Linux\u3011\u3010\u6e90\u7801\u89e3\u6790\u3011epoll\u8f6f\u4ef6\u67b6\u6784\u53ca\u539f\u7406"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\">epoll\u539f\u7406\u53ca\u5b9e\u73b0<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">\u4e00\u3001 \u53d1\u5c55\u5386\u53f2<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">API \u53d1\u5e03\u7684\u65f6\u95f4\u7ebf<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u4e0b\u6587\u4e2d\u5217\u51fa\u4e86\u7f51\u7edc <code>IO<\/code>\u4e2d\uff0c\u5404\u4e2a<code>api<\/code>\u7684\u53d1\u5e03\u65f6\u95f4\u7ebf<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">1983\uff0csocket \u53d1\u5e03\u5728 Unix(4.2 BSD)<br>1983\uff0cselect \u53d1\u5e03\u5728 Unix(4.2 BSD)<br>1994\uff0cLinux\u76841.0\uff0c\u5df2\u7ecf\u652f\u6301socket\u548cselect<br>1997\uff0cpoll \u53d1\u5e03\u5728 Linux 2.1.23<br>2002\uff0cepoll\u53d1\u5e03\u5728 Linux 2.5.44<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">\u53ef\u4ee5\u770b\u5230<code>select<\/code>\u3001<code>poll<\/code> \u548c <code>epoll<\/code>\uff0c\u8fd9\u4e09\u4e2a\u201c<code>IO<\/code>\u591a\u8def\u590d\u7528<code>API<\/code>\u201d\u662f\u76f8\u7ee7\u53d1\u5e03\u7684\u3002\u8fd9\u8bf4\u660e\u4e86\uff0c\u5b83\u4eec\u662f<code>IO<\/code>\u591a\u8def\u590d\u7528\u7684<code>3<\/code>\u4e2a\u8fdb\u5316\u7248\u672c\u3002\u56e0\u4e3a<code>API<\/code>\u8bbe\u8ba1\u7f3a\u9677\uff0c\u65e0\u6cd5\u5728\u4e0d\u6539\u53d8 <code>API<\/code> \u7684\u524d\u63d0\u4e0b\u4f18\u5316\u5185\u90e8\u903b\u8f91\u3002\u6240\u4ee5\u7528<code>poll<\/code>\u66ff\u4ee3<code>select<\/code>\uff0c\u518d\u7528<code>epoll<\/code>\u66ff\u4ee3<code>poll<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>epoll<\/code>\u548c<code>poll<\/code>\u8fd8\u6709<code>select<\/code>\u90fd\u662f\u76d1\u542c<code>socket<\/code>\u7684\u63a5\u53e3\uff0c<code>poll<\/code>\u8fd8\u6709<code>select<\/code>\u51fa\u73b0\u7684\u65f6\u95f4\u66f4\u65e9\uff0c\u4f46\u662f\u6027\u80fd\u66f4\u5dee\u3002\u540e\u6765\u5728\u6b64\u7ee7\u627f\u4e0a\u53d1\u5c55\u6539\u8fdb\u5f97\u5230\u4e86<code>epoll<\/code><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u4e8c\u3001epoll\u662f\u4ec0\u4e48<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><code>epoll<\/code>\u662f\u4e00\u79cd<code>I\/O<\/code>\u4e8b\u4ef6\u901a\u77e5\u673a\u5236\uff0c\u662f<code>linux<\/code>\u5185\u6838\u5b9e\u73b0<code>IO<\/code>\u591a\u8def\u590d\u7528\u7684\u4e00\u4e2a\u5b9e\u73b0<br><code>IO<\/code>\u591a\u8def\u590d\u7528\u662f\u6307\uff0c\u5728\u4e00\u4e2a\u64cd\u4f5c\u91cc\u540c\u65f6\u76d1\u542c\u591a\u4e2a\u8f93\u5165\u8f93\u51fa\u6e90\uff0c\u5728\u5176\u4e2d\u4e00\u4e2a\u6216\u591a\u4e2a\u8f93\u5165\u8f93\u51fa\u6e90\u53ef\u7528\u7684\u65f6\u5019\u8fd4\u56de\uff0c\u7136\u540e\u5bf9\u5176\u7684\u8fdb\u884c\u8bfb\u5199\u64cd\u4f5c<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>epoll<\/code>\u7684\u901a\u4fd7\u89e3\u91ca\u662f\u4e00\u79cd\u5f53\u6587\u4ef6\u63cf\u8ff0\u7b26\u7684\u5185\u6838\u7f13\u51b2\u533a\u975e\u7a7a\u7684\u65f6\u5019\uff0c\u53d1\u51fa\u53ef\u8bfb\u4fe1\u53f7\u8fdb\u884c\u901a\u77e5\uff0c\u5f53\u5199\u7f13\u51b2\u533a\u4e0d\u6ee1\u7684\u65f6\u5019\uff0c\u53d1\u51fa\u53ef\u5199\u4fe1\u53f7\u901a\u77e5\u7684\u673a\u5236<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u4e09\u3001epoll\u63a5\u53e3\u793a\u4f8b\u4ee3\u7801<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1. \u76d1\u542c\u952e\u76d8\u8f93\u5165<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u521b\u5efa\u4e00\u4e2a<code>epoll<\/code>\u8fde\u63a5\uff0c\u76d1\u542c\u6807\u51c6\u8f93\u5165\u3002\u6253\u5370\u7528\u6237\u8f93\u5165\u7684\u503c\uff0c\u82e5\u8f93\u5165<code>exit<\/code>\u5219\u76f4\u63a5\u9000\u51fa\u7ed3\u675f\u8fdb\u7a0b<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h>\n#include &lt;string.h>\n#include &lt;unistd.h>\n#include &lt;errno.h>\n#include &lt;sys\/epoll.h>\n\n#define MAX_EVENTS 10\n\nstatic int create_epoll_event()\n{\n    int epoll_fd;\n    struct epoll_event event = {0};\n\n    epoll_fd = epoll_create1(0);\n    if (epoll_fd &lt; 0)\n        return -1;\n\n    event.events = EPOLLIN;\n    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, STDIN_FILENO, &amp;event) != 0) {\n        close(epoll_fd);\n        return -1;\n    }\n\n    return epoll_fd;\n}\n\nint main()\n{\n    int n = -1;\n    int nfds = -1;\n    int epoll_fd = -1;\n    ssize_t nr = 0;\n    char buf&#91;256] = {0};\n    struct epoll_event events&#91;MAX_EVENTS] = {0};\n\n    epoll_fd = create_epoll_event();\n    if (epoll_fd &lt; 0) {\n        perror(\"create_epoll_event\");\n        return 1;\n    }\n\n    while (1) {\n        \/\/ \u7b49\u5f85\u4e8b\u4ef6\u53d1\u751f\n        nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);\n        if (nfds &lt; 0) {\n            if (errno == EINTR)\n                continue;\n            perror(\"epoll_wait\");\n            goto cleanup;\n        }\n\n        \/\/ \u5904\u7406\u5c31\u7eea\u7684\u4e8b\u4ef6\n        for (n = 0; n &lt; nfds; ++n) {\n            if (events&#91;n].data.fd == STDIN_FILENO) {\n                \/\/ \u4ece\u6807\u51c6\u8f93\u5165\u4e2d\u8bfb\u53d6\u6570\u636e\n                nr = read(events&#91;n].data.fd, buf, sizeof(buf) - 1);\n                if (nr &lt; 0) {\n                    perror(\"read\");\n                    goto cleanup;\n                }\n                if (nr == 0)\n                    goto cleanup;\n                buf&#91;nr] = '\\0';\n                printf(\"Received input: %s\", buf);\n                \/\/ \u5982\u679c\u6536\u5230exit\uff0c\u5219\u9000\u51fa\u5faa\u73af\n                if (strcmp(buf, \"exit\\n\") == 0) {\n                    goto cleanup;\n                }\n            }\n        }\n    }\n\ncleanup:\n    if (epoll_fd >= 0)\n        close(epoll_fd);\n    return 0;\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">2. \u76d1\u542c\u672c\u5730socket\u6587\u4ef6<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>server\u7aef<\/strong><br>\u521b\u5efa\u672c\u5730<code>socket<\/code>\u6587\u4ef6<code>\/tmp\/epoll_demo.sock<\/code>\u5e76\u7528<code>epoll<\/code>\u76d1\u542c\uff0c\u6253\u5370\u6536\u5230\u7684\u6d88\u606f\uff0c\u5982\u679c\u6d88\u606f\u662f<code>exit<\/code>\u5219\u4f1a\u76f4\u63a5\u7ed3\u675f\u8fdb\u7a0b<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/*\n * epoll_server.c\n * \u4f5c\u4e3a\u670d\u52a1\u7aef\uff0c\u76d1\u542c\u672c\u5730\u5957\u63a5\u5b57\uff0c\u63a5\u53d7\u5ba2\u6237\u7aef\u8fde\u63a5\uff0c\u5e76\u5904\u7406\u5ba2\u6237\u7aef\u53d1\u6765\u7684\u6d88\u606f\u3002\n *\/\n\n#include &lt;errno.h>\n#include &lt;stdio.h>\n#include &lt;stdlib.h>\n#include &lt;string.h>\n#include &lt;sys\/epoll.h>\n#include &lt;sys\/socket.h>\n#include &lt;sys\/un.h>\n#include &lt;unistd.h>\n\n#define MAX_EVENTS 10\n\n\/* \u76d1\u542c\u5957\u63a5\u5b57\uff08listening socket\uff09\u53e5\u67c4\uff0c\u4f9b epoll \u4e0e accept \u4f7f\u7528 *\/\nstatic const char SOCK_PATH&#91;] = \"\/tmp\/epoll_demo.sock\";\n\nstatic void stop_server()\n{\n    printf(\"\u670d\u52a1\u5668\u9000\u51fa\\n\");\n    exit(0);\n}\n\nstatic void clean_local_socket(const int lfd)\n{\n    if (lfd >= 0)\n        close(lfd);\n\n    unlink(SOCK_PATH);\n}\n\nstatic int create_local_socket(int *lfd)\n{\n    int ret = 0;\n\n    *lfd = socket(AF_UNIX, SOCK_STREAM, 0);\n    if (*lfd &lt; 0) {\n        ret = -1;\n        perror(\"socket\");\n        goto end;\n    }\n\nend:\n    return ret;\n}\n\nstatic int listen_local_socket(int lfd)\n{\n    int ret = 0;\n    struct sockaddr_un addr = {0};\n\n    unlink(SOCK_PATH);\n    addr.sun_family = AF_UNIX;\n    snprintf(addr.sun_path, sizeof(addr.sun_path), \"%s\", SOCK_PATH);\n\n    ret = bind(lfd, (struct sockaddr *)&amp;addr, sizeof(addr));\n    if (ret &lt; 0) {\n        perror(\"bind\");\n        goto end;\n    }\n\n    ret = listen(lfd, MAX_EVENTS);\n    if (ret &lt; 0) {\n        perror(\"listen\");\n        goto end;\n    }\n\n    printf(\"\u76d1\u542c %s \u4e2d...\\n\", SOCK_PATH);\nend:\n    return ret;\n}\n\n\/* \u5904\u7406\u5ba2\u6237\u7aef\u53d1\u6765\u7684\u6d88\u606f *\/\nstatic void handle_client_data(int epfd, int cfd)\n{\n    char buf&#91;1024] = {0};\n    ssize_t nr = 0;\n\n    nr = read(cfd, buf, sizeof(buf) - 1);\n    \/* read \u8fd4\u56de 0\uff1a\u5bf9\u7aef\u5173\u95ed\uff1bLT \u4e0b\u82e5\u4e0d epoll_del+close\uff0c\u4f1a\u4e00\u76f4\u53ef\u8bfb *\/\n    if (nr &lt;= 0) {\n        epoll_ctl(epfd, EPOLL_CTL_DEL, cfd, NULL);\n        close(cfd);\n        goto end;\n    }\n\n    buf&#91;nr] = '\\0';\n    if (strcmp(buf, \"exit\") == 0)\n        stop_server();\n    else\n        printf(\"\u6536\u5230: %s\\n\", buf);\n\nend:\n    fflush(stdout);\n}\n\n\/* \u65b0\u5ba2\u6237\u7aef\u5728 Unix \u57df\u6d41\u5957\u63a5\u5b57\u4e0a\u8fde\u63a5\u6210\u529f\uff0c\u5c06 accept \u5f97\u5230\u7684\u53e5\u67c4\u52a0\u5165 epoll \u76d1\u542c *\/\nstatic int handle_client_connect(int epfd, int fd)\n{\n    int ret = 0;\n    int cfd = -1;\n    struct epoll_event ev = {0};\n\n    cfd = accept(fd, NULL, NULL);\n    if (cfd &lt; 0) {\n        ret = cfd;\n        perror(\"accept\");\n        goto end;\n    }\n\n    ev.events = EPOLLIN;\n    ret = epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &amp;ev);\n    if (ret &lt; 0) {\n        perror(\"epoll_ctl\");\n        close(cfd);\n        goto end;\n    }\n\nend:\n    return ret;\n}\n\n\/* \u4f7f\u7528 epoll\uff08\u4e8b\u4ef6\u8f6e\u8be2\uff0c\u9ed8\u8ba4\u6c34\u5e73\u89e6\u53d1 LT\uff09\u76d1\u542c lfd \u4e0e\u65b0\u63a5\u53d7\u7684\u8fde\u63a5 *\/\nstatic int run_epoll_demo(int lfd)\n{\n    int n = -1;\n    int i = -1;\n    int ret = 0;\n    int epfd = -1;\n    struct epoll_event ev = {0};\n    struct epoll_event events&#91;MAX_EVENTS] = {0};\n\n    ev.events = EPOLLIN;\n    ev.data.fd = lfd;\n\n    epfd = epoll_create1(0);\n    if (epfd &lt; 0) {\n        ret = epfd;\n        perror(\"epoll_create1\");\n        goto end;\n    }\n\n    ret = epoll_ctl(epfd, EPOLL_CTL_ADD, lfd, &amp;ev);\n    if (ret &lt; 0) {\n        perror(\"epoll_ctl\");\n        goto end;\n    }\n\n    while(1) {\n        n = epoll_wait(epfd, events, sizeof(events) \/ sizeof(events&#91;0]), -1);\n        if (n &lt; 0) {\n            ret = n;\n            perror(\"epoll_wait\");\n            goto end;\n        }\n\n        for (i = 0; i &lt; n; i++) {\n            if (events&#91;i].data.fd == lfd) {\n                \/* \u65b0\u5ba2\u6237\u7aef\u8fde\u63a5\u6210\u529f *\/\n                ret = handle_client_connect(epfd, events&#91;i].data.fd);\n                if (ret &lt; 0) {\n                    perror(\"handle_client_connect\");\n                    goto end;\n                }\n            } else {\n                \/* \u5df2\u6709\u5ba2\u6237\u7aef\u53d1\u6765\u6d88\u606f\uff0c\u5904\u7406\u6570\u636e *\/\n                handle_client_data(epfd, events&#91;i].data.fd);\n            }\n        }\n    }\n\nend:\n    if (epfd >= 0)\n        close(epfd);\n\n    return ret;\n}\n\nint main(void)\n{\n    int ret = -1;\n    int lfd = -1;\n\n    ret = create_local_socket(&amp;lfd);\n    if (ret &lt; 0) {\n        perror(\"create_local_socket\");\n        return 1;\n    }\n\n    ret = listen_local_socket(lfd);\n    if (ret &lt; 0) {\n        perror(\"listen_local_socket\");\n        clean_local_socket(lfd);\n        return 1;\n    }\n\n    ret = run_epoll_demo(lfd);\n    if (ret &lt; 0) {\n        perror(\"run_epoll_demo\");\n        clean_local_socket(lfd);\n        return 1;\n    }\n\n    clean_local_socket(lfd);\n\n    return 0;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>client\u7aef<\/strong><br>\u521b\u5efa<code>socket<\/code>\u7ed1\u5b9a\u5230<code>\/tmp\/epoll_demo.sock<\/code>\uff0c\u901a\u8fc7<code>socket<\/code>\u53d1\u9001\u6d88\u606f<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/**\n * epoll_client.c\n * \u4f5c\u4e3a\u5ba2\u6237\u7aef\uff0c\u8fde\u63a5\u672c\u5730\u5957\u63a5\u5b57\uff0c\u5e76\u53d1\u9001\u6d88\u606f\u7ed9\u670d\u52a1\u7aef\n *\/\n\n#include &lt;stdio.h&gt;\n#include &lt;string.h&gt;\n#include &lt;sys\/socket.h&gt;\n#include &lt;sys\/un.h&gt;\n#include &lt;unistd.h&gt;\n\nstatic const char SOCK_PATH&#91;] = \"\/tmp\/epoll_demo.sock\";\n\nstatic void create_socket(int *fd)\n{\n    struct sockaddr_un addr = {0};\n\n    addr.sun_family = AF_UNIX;\n    snprintf(addr.sun_path, sizeof(addr.sun_path), \"%s\", SOCK_PATH);\n\n    *fd = socket(AF_UNIX, SOCK_STREAM, 0);\n    connect(*fd, (struct sockaddr *)&amp;addr, sizeof(addr));\n}\n\nstatic void send_message(char *message, const int fd)\n{\n    char buf&#91;1024] = {0};\n\n    snprintf(buf, sizeof(buf), \"%s\", message);\n    send(fd, buf, strlen(buf) + 1, 0);\n}\n\n\/* \u4f5c\u4e3a\u5ba2\u6237\u7aef(client)\u8fde\u63a5epoll_server\u76d1\u542c\u7684\u672c\u5730\u5957\u63a5\u5b57\u5e76\u53d1\u9001\u6570\u636e *\/\nint main(int argc, char *argv&#91;])\n{\n    int fd = -1;\n\n    if(argc &lt; 2) {\n        printf(\"Usage: %s &lt;message&gt;\\n\", argv&#91;0]);\n        printf(\"if want to exit, send 'exit' message\\n\");\n        return 1;\n    }\n\n    create_socket(&amp;fd);\n    send_message(argv&#91;1], fd);\n\n    if (fd &gt; 0)\n        close(fd);\n\n    return 0;\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">\u56db\u3001\u9501\u4e0e\u5185\u5b58\u5c4f\u969c\u95ee\u9898\uff08\u5199\u5728\u524d\u9762\uff09<\/h2>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u672c\u6587\u5bf9<strong>\u591a\u8fdb\u7a0b\u4e0b\u9501\u7684\u8c03\u5ea6\u4e0e\u4f7f\u7528\u4ee5\u53ca\u591aCPU\u4e0b\u4e0e\u5185\u5b58\u5c4f\u969c\u95ee\u9898<\/strong>\u90e8\u5206\u4e0d\u505a\u5c55\u5f00<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u5173\u4e8eepoll\u6a21\u5757\u5bf9\u4e8e\u591a\u8fdb\u7a0b\u4e0b\u9501\u7684\u5904\u7406<\/strong><br>\u9644\u4e0a\u6e90\u4ee3\u7801\u4e2d\u6ce8\u91ca\u4e00\u6bb5\uff0c\u4f9b\u8bfb\u8005\u81ea\u884c\u7406\u89e3<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u6240\u6709\u4ee3\u7801\u5747\u672a\u5220\u6539<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ linux-5.4\/fs\/eventpoll.c\n\n\/*\n * LOCKING:\n * There are three level of locking required by epoll :\n *\n * 1) epmutex (mutex)\n * 2) ep-&gt;mtx (mutex)\n * 3) ep-&gt;lock (rwlock)\n *\n * The acquire order is the one listed above, from 1 to 3.\n * We need a rwlock (ep-&gt;lock) because we manipulate objects\n * from inside the poll callback, that might be triggered from\n * a wake_up() that in turn might be called from IRQ context.\n * So we can't sleep inside the poll callback and hence we need\n * a spinlock. During the event transfer loop (from kernel to\n * user space) we could end up sleeping due a copy_to_user(), so\n * we need a lock that will allow us to sleep. This lock is a\n * mutex (ep-&gt;mtx). It is acquired during the event transfer loop,\n * during epoll_ctl(EPOLL_CTL_DEL) and during eventpoll_release_file().\n * Then we also need a global mutex to serialize eventpoll_release_file()\n * and ep_free().\n * This mutex is acquired by ep_free() during the epoll file\n * cleanup path and it is also acquired by eventpoll_release_file()\n * if a file has been pushed inside an epoll set and it is then\n * close()d without a previous call to epoll_ctl(EPOLL_CTL_DEL).\n * It is also acquired when inserting an epoll fd onto another epoll\n * fd. We do this so that we walk the epoll tree and ensure that this\n * insertion does not create a cycle of epoll file descriptors, which\n * could lead to deadlock. We need a global mutex to prevent two\n * simultaneous inserts (A into B and B into A) from racing and\n * constructing a cycle without either insert observing that it is\n * going to.\n * It is necessary to acquire multiple \"ep-&gt;mtx\"es at once in the\n * case when one epoll fd is added to another. In this case, we\n * always acquire the locks in the order of nesting (i.e. after\n * epoll_ctl(e1, EPOLL_CTL_ADD, e2), e1-&gt;mtx will always be acquired\n * before e2-&gt;mtx). Since we disallow cycles of epoll file\n * descriptors, this ensures that the mutexes are well-ordered. In\n * order to communicate this nesting to lockdep, when walking a tree\n * of epoll file descriptors, we use the current recursion depth as\n * the lockdep subkey.\n * It is possible to drop the \"ep-&gt;mtx\" and to use the global\n * mutex \"epmutex\" (together with \"ep-&gt;lock\") to have it working,\n * but having \"ep-&gt;mtx\" will make the interface more scalable.\n * Events that require holding \"epmutex\" are very rare, while for\n * normal operations the epoll private \"ep-&gt;mtx\" will guarantee\n * a better scalability.\n *\/<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">\u4e94\u3001\u6838\u5fc3\u6570\u636e\u7ed3\u6784<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1. struct eventpoll<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u8fd9\u4e2a\u6570\u636e\u7ed3\u6784\u662f\u6211\u4eec\u5728\u8c03\u7528<code>epoll_create<\/code>\u4e4b\u540e\u5185\u6838\u4fa7\u521b\u5efa\u7684\u4e00\u4e2a\u53e5\u67c4\uff0c\u8868\u793a\u4e86\u4e00\u4e2a<code>epoll<\/code>\u5b9e\u4f8b\u3002\u540e\u7eed\u5982\u679c\u6211\u4eec\u518d\u8c03\u7528<code>epoll_ctl<\/code>\u548c<code>epoll_wait<\/code>\u7b49\uff0c\u90fd\u662f\u5bf9\u8fd9\u4e2a<code>eventpoll<\/code>\u6570\u636e\u8fdb\u884c\u64cd\u4f5c\uff0c\u8fd9\u90e8\u5206\u6570\u636e\u4f1a\u88ab\u4fdd\u5b58\u5728<code>do_epoll_create<\/code>\u521b\u5efa\u7684\u533f\u540d\u6587\u4ef6<code>file<\/code>\u7684<code>private_data<\/code>\u5b57\u6bb5\u4e2d<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u9664\u6ce8\u91ca\u5916\uff0c\u6240\u6709\u4ee3\u7801\u5747\u672a\u5220\u6539<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ linux-5.4\/fs\/eventpoll.c\n\/*\n * Each file descriptor added to the eventpoll interface will\n * have an entry of this type linked to the \"rbr\" RB tree.\n * Avoid increasing the size of this struct, there can be many thousands\n * of these on a server and we do not want this to take another cache line.\n *\/\nstruct eventpoll {\n    \/**\n     * ep-&gt;mtx\u4fdd\u62a4\u7684\u662f\u8fd9\u4e2aeventpoll\u5b9e\u4f8b\u5728\u903b\u8f91\u4e0a\u7684\u5b8c\u6574\u6027\u4e0e\u751f\u547d\u5468\u671f\u76f8\u5173\u64cd\u4f5c\n     * \u8c01\u5728\u96c6\u5408\u91cc\u3001epitem\u600e\u4e48\u6302\/\u62c6\u3001\u548c\u5e95\u5c42file\u7684\u5173\u8054\u4f55\u65f6\u5931\u6548\u2014\u2014\u672c\u8d28\u4e0a\u5c31\u662fep\u72b6\u6001\u673a\u4e0d\u8981\u88abepoll_wait\/epoll_ctl\/close\u7b49\u8def\u5f84\u6253\u4e71\n     *\/\n    struct mutex mtx;\n\n    \/**\n     * \u7b49\u5f85\u961f\u5217\uff0c\u6267\u884cepoll_Wait\u52a0\u5165\u7b49\u5f85\u961f\u5217\n     * epoll_wait()\u91cc\u963b\u585e\u7684\u8fdb\u7a0b\u6302\u5728\u8fd9\u4e2a\u7b49\u5f85\u961f\u5217\u4e0a\n     * \u6709\u5c31\u7eea\u4e8b\u4ef6\u6216\u9700\u8981\u5524\u9192\u7b49\u5f85\u8005\u65f6\uff0c\u4f1awake_up\u8fd9\u91cc\n     *\/\n    wait_queue_head_t wq;\n\n    \/** \n     * \u7b49\u5f85\u961f\u5217\u7684file-&gt;poll()\n     * \u8fd9\u4e2a\u961f\u5217\u91cc\u5b58\u653e\u7684\u662f\u8be5eventloop\u4f5c\u4e3apoll\u5bf9\u8c61\u7684\u4e00\u4e2a\u5b9e\u4f8b\uff0c\u52a0\u5165\u5230\u7b49\u5f85\u7684\u961f\u5217\n     * \u8fd9\u662f\u56e0\u4e3aeventpoll\u672c\u8eab\u4e5f\u662f\u4e00\u4e2afile, \u6240\u4ee5\u4e5f\u4f1a\u6709poll\u64cd\u4f5c\n     *\/\n    wait_queue_head_t poll_wait;\n\n    \/* \u5c31\u7eea\u94fe\u8868 *\/\n    struct list_head rdllist;\n\n    \/* \u7528\u4e8erdllist\u548covflist\u7684\u8bfb\u5199\u9501 *\/\n    rwlock_t lock;\n\n    \/* \u6307\u5411\u88ab\u68c0\u89c6\u5bf9\u8c61\u5b58\u50a8\u7684\u7ea2\u9ed1\u6811 *\/\n    struct rb_root_cached rbr;\n\n    \/**\n     * \u5f53\u5411\u7528\u6237\u7a7a\u95f4\u62f7\u8d1d\u5c31\u7eea\u4e8b\u4ef6\u7684\u8fc7\u7a0b\u4e2d\uff0c\u6709\u65f6\u5019\u4e0d\u80fd\u6301\u6709-&gt;lock\u9501\uff0c\u5c31\u4f1a\u5c06\u4e8b\u4ef6\u653e\u5728\u8fd9\u91cc\n     * \u4e4b\u540e\u6dfb\u52a0\u5230\u6b63\u5f0f\u7684\u5c31\u7eea\u961f\u5217\u4e2d\n     *\/\n    struct epitem *ovflist;\n\n    \/* \u7535\u6e90\u7ba1\u7406\u76f8\u5173\u5524\u9192\u6e90 *\/\n    struct wakeup_source *ws;\n\n    \/* \u521b\u5efaeventpoll\u63cf\u8ff0\u7b26\u7684\u7528\u6237 *\/\n    struct user_struct *user;\n\n    \/**\n     * epoll fd\u81ea\u8eab\u5bf9\u5e94\u7684struct file\n     * \u4fbf\u4e8e\u4eceeventpoll\u53cd\u67e5VFS\u5c42\u6587\u4ef6\u3001\u4e0e f_op\u3001\u5f15\u7528\u8ba1\u6570\u7b49\u8854\u63a5\n     *\/\n    struct file *file;\n\n    \/* \u7528\u4e8e\u68c0\u6d4b\u662f\u5426\u6709\u5d4c\u5957\u8c03\u7528\u9020\u6210\u73af\u8def *\/\n    int visited;\n    struct list_head visited_list_link;\n\n    \/**\n     * \u5728\u5f00\u542f\u7f51\u7edcRX busy polling\u65f6\n     * \u7528\u4e8e\u8ddf\u8e2a\u4e0eNAPI(\u7f51\u7edc\u4e2d\u65ad\u7f13\u89e3\u63a5\u53e3)\u76f8\u5173\u7684 napi_id\n     * \u4f7fepoll\u8def\u5f84\u80fd\u4e0e\u7f51\u5361\u4fa7\u7684busy poll\u4f18\u5316\u534f\u4f5c\n     *\/\n    unsigned int napi_id;\n};<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6838\u5fc3\u601d\u60f3<\/strong><br><code>struct eventpoll<\/code> \u662f\u6bcf\u4e2a<code>epoll<\/code>\u5b9e\u4f8b \u7684\u6838\u5fc3\u4e0a\u4e0b\u6587\uff0c\u521b\u5efa <code>epoll_create*<\/code>\u65f6\u5206\u914d\uff0c\u6302\u5728\u5bf9\u5e94<code>struct file<\/code>\u7684<code>private_data<\/code>\u4e0a<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>mtx<\/code>\u4e92\u65a5\u9501\u786e\u4fdd<code>epoll<\/code>\u6574\u4f53\u903b\u8f91\u7684\u5b8c\u6574\uff0c<code>lock<\/code>\u786e\u4fdd<code>rdllist<\/code>\u961f\u5217\u548c<code>ovflist<\/code>\u961f\u5217\u8bfb\u5199\u5b89\u5168<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>wp<\/code>\u961f\u5217\u548c<code>poll_wait<\/code>\u961f\u5217\u90fd\u662f\u5185\u6838\u7b49\u5f85\u961f\u5217\uff0c<code>wp<\/code>\u961f\u5217\u5411\u7528\u6237\u6001<code>epoll_wait<\/code>\u8c03\u7528\u8005\u63d0\u4f9b\u3002<code>poll_wait<\/code>\u961f\u5217\u5219\u662f\u5f53\u5411<code>VFS<\/code>\u7cfb\u7edf\u63d0\u4f9b\u7684\uff0c\u5f53\u522b\u7684\u4ee3\u7801\u5bf9\u8fd9\u4e2a<code>epoll<\/code>\u7684<code>file<\/code>\u505a <code>poll\/select<\/code>\u65f6\u7528\u7684\u7b49\u5f85\u961f\u5217<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/struct_eventpoll-2822x4096.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"2822\" height=\"4096\" data-original=\"https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/struct_eventpoll-2822x4096.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-525\"  sizes=\"auto, (max-width: 2822px) 100vw, 2822px\" \/><\/div><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">1) wq\u961f\u5217<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\"><code>wq<\/code>\u961f\u5217\u662f\u9762\u5411\u7528\u6237\u6001\u7684<code>epoll_wait<\/code>\u7684\u8c03\u7528\u8005\u63d0\u4f9b<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u4ec5\u5728ep_poll\u51fd\u6570\u4e2d\u4f7f\u7528<\/strong><br><strong>\u5728\u8fd9\u4e9b\u573a\u666f\u4e2d\u4f1a\u4f7f\u7528\u6765wake_up(&amp;ep-&gt;wq)\u5524\u9192\u7b49\u5f85\u8005<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u76d1\u542c\u53e5\u67c4\u6d3b\u8dc3\uff0c\u89e6\u53d1<code>ep_poll_callback<\/code><\/li>\n\n\n\n<li><code>ep_scan_ready_list<\/code>\u4e2d\u5237\u65b0\u5b8c\u5c31\u7eea\u961f\u5217\u540e\uff0c\u68c0\u67e5\u4e00\u6b21\uff0c\u5982\u679c\u6709\u5c31\u7eea\u4e8b\u4ef6\uff0c\u628a\u5b83\u63a8\u8fdb <code>rdllist<\/code> \u5e76\u5524\u9192\u7b49\u5f85\u8005<\/li>\n\n\n\n<li><code>ep_insert<\/code>\u4e2d\u63d2\u5165\u8282\u70b9\u540e\uff0c\u7acb\u523b\u68c0\u67e5\u4e00\u6b21\uff0c\u5982\u679c\u6709\u5c31\u7eea\u4e8b\u4ef6\uff0c\u628a\u5b83\u63a8\u8fdb <code>rdllist<\/code> \u5e76\u5524\u9192\u7b49\u5f85\u8005<\/li>\n\n\n\n<li><code>ep_modify<\/code>\u4fee\u6539\u4e86\u67d0\u4e2a\u5df2\u6ce8\u518c<code>fd<\/code>\u7684 <code>epoll_event<\/code> \u4e4b\u540e\uff0c\u7acb\u523b\u68c0\u67e5\u4e00\u6b21\uff0c\u5982\u679c\u6709\u5c31\u7eea\u4e8b\u4ef6\uff0c\u628a\u5b83\u63a8\u8fdb <code>rdllist<\/code> \u5e76\u5524\u9192\u7b49\u5f85\u8005<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">2) poll_wait\u961f\u5217<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\"><code>epoll_create<\/code>\u521b\u5efa\u7684<code>epoll<\/code>\u5b9e\u4f8b\u672c\u8eab\uff0c\u4e5f\u53ef\u4ee5\u88ab\u5f53\u505a\u4e00\u4e2a\u53e5\u67c4\u6765\u76d1\u542c\uff0c<code>poll_wait<\/code>\u961f\u5217\u5c31\u662f\u5e94\u5bf9\u8fd9\u79cd\u60c5\u51b5\u4f7f\u7528\u7684<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u5728\u8fd9\u4e9b\u573a\u666f\u4e2d\u4f1a\u4f7f\u7528poll_wait()\u51fd\u6570\u6765\u5411poll_wait\u961f\u5217\u4e2d\u6dfb\u52a0\u6210\u5458<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><code>ep_item_poll<\/code>\u51fd\u6570\u5bf9<code>epitem<\/code>\u8282\u70b9\uff0c\u6240\u5bf9\u5e94\u7684<code>file<\/code>\u505a\u4e00\u6b21\u4e0e<code>poll<\/code>\u7b49\u4ef7\u8bed\u4e49\u7684\u63a2\u6d4b<br>\u8fd9\u65f6\u4f1a\u68c0\u6d4b\u63a2\u6d4b\u7684\u662f\u5426\u662f<code>epoll<\/code>\u6587\u4ef6\uff0c\u5982\u679c\u662f\u5219\u4f7f\u7528<code>poll_wait()<\/code>\u51fd\u6570\u5c06\u81ea\u8eab\u6dfb\u52a0\u5230<code>poll_wait<\/code>\u961f\u5217\u4e2d\u3002\u8fd9\u91cc\u5916\u5c42<code>epoll<\/code>\u5728\u7b49\u5f85\u7684\u5e76\u4e0d\u662f\u5185\u5c42<code>epoll<\/code>\u6587\u4ef6\u7684\u67d0\u4e2a\u8bbe\u5907\u961f\u5217\u672c\u8eab\uff0c\u800c\u662f\u5185\u5c42<code>struct eventpoll<\/code>\u7684\u7b49\u5f85\u961f\u5217\u5934<code>poll_wait<\/code>\uff1b\u8fd9\u6837\u5d4c\u5957<code>epoll<\/code>\u624d\u80fd\u50cf\u666e\u901a<code>fd<\/code>\u4e00\u6837\u88ab<code>poll<\/code>\u9a71\u52a8<\/li>\n\n\n\n<li><code>epoll<\/code>\u6a21\u5757\u5bf9<code>VFS<\/code>\u63d0\u4f9b\u7684<code>poll<\/code>\u63a5\u53e3\u56de\u8c03\u51fd\u6570<code>ep_eventpoll_poll<\/code>\u4e2d \u8fd9\u91cc\u5c06\u7b49\u5f85\u8005\u6302\u5728<code>epoll<\/code>\u7684\u7b49\u5f85\u961f\u5217\u4e2d\uff0c\u662f\u4e00\u4e2a\u5e38\u89c4\u64cd\u4f5c\uff0c\u662f<code>poll<\/code>\u63a5\u53e3\u5b9e\u73b0\u975e\u5e38\u5e38\u89c1\u7684\u4e00\u79cd\u505a\u6cd5<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">\u8fd9\u4e8c\u8005\u7684\u533a\u522b\u662f\u4e00\u4e2a\u662f\u901a\u8fc7<code>epoll_ctl<\/code>\u63a5\u53e3\u5c06\u5f85\u68c0\u6d4b\u7684\u53e5\u67c4\u4f20\u5165\u5185\u6838\uff0c\u5728<code>epoll<\/code>\u6d41\u7a0b\u4e2d\u7684<code>ep_item_poll<\/code>\u51fd\u6570\u4f1a\u68c0\u6d4b\u4e8b\u4ef6\u6d3b\u8dc3\u3002\u53e6\u4e00\u4e2a\u4f7f\u7528\u76f4\u63a5\u4f7f\u7528<code>epoll<\/code>\u5728<code>VFS<\/code>\u4e2d\u6ce8\u518c\u7684<code>poll<\/code>\u63a5\u53e3<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u5728\u8fd9\u4e9b\u573a\u666f\u4e2d\u4f1a\u4f7f\u7528\u6765ep_poll_safewake(&amp;ep-&gt;poll_wait)\u5524\u9192\u7b49\u5f85\u8005<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u76d1\u542c\u53e5\u67c4\u6d3b\u8dc3\uff0c\u89e6\u53d1<code>ep_poll_callback<\/code><\/li>\n\n\n\n<li><code>ep_scan_ready_list<\/code>\u4e2d\u5237\u65b0\u5b8c\u5c31\u7eea\u961f\u5217\u540e\uff0c\u68c0\u67e5\u4e00\u6b21\uff0c\u5982\u679c\u6709\u5c31\u7eea\u4e8b\u4ef6\uff0c\u628a\u5b83\u63a8\u8fdb <code>rdllist<\/code> \u5e76\u5524\u9192\u7b49\u5f85\u8005<\/li>\n\n\n\n<li><code>ep_insert<\/code>\u4e2d\u63d2\u5165\u8282\u70b9\u540e\uff0c\u7acb\u523b\u68c0\u67e5\u4e00\u6b21\uff0c\u5982\u679c\u6709\u5c31\u7eea\u4e8b\u4ef6\uff0c\u628a\u5b83\u63a8\u8fdb <code>rdllist<\/code> \u5e76\u5524\u9192\u7b49\u5f85\u8005<\/li>\n\n\n\n<li><code>ep_modify<\/code>\u4fee\u6539\u4e86\u67d0\u4e2a\u5df2\u6ce8\u518c<code>fd<\/code>\u7684 <code>epoll_event<\/code> \u4e4b\u540e\uff0c\u7acb\u523b\u68c0\u67e5\u4e00\u6b21\uff0c\u5982\u679c\u6709\u5c31\u7eea\u4e8b\u4ef6\uff0c\u628a\u5b83\u63a8\u8fdb <code>rdllist<\/code> \u5e76\u5524\u9192\u7b49\u5f85\u8005<\/li>\n\n\n\n<li><code>ep_free<\/code>\u51fd\u6570<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">3) ovflist\u961f\u5217\u7684\u542f\u7528<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\"><code>ovflist<\/code>\u5728\u521d\u59cb\u5316\u548c\u4e0d\u88ab\u542f\u7528\u65f6\u4f1a\u88ab\u6307\u5411<code>EP_UNACTIVE_PTR<\/code>\u8fd9\u4e2a\u7279\u6b8a\u503c\uff0c\u5728<code>ep_scan_ready_list<\/code>\u51fd\u6570\u4e2d\u5bf9<code>rdllist<\/code>\u64cd\u4f5c\u65f6\uff0c\u8fd9\u65f6\u4e0d\u80fd\u5199\u5165<code>rdllist<\/code>\u3002\u5c31\u4f1a\u5148\u5c06<code>ovflist<\/code>\u6307\u5411<code>NULL<\/code>\uff0c\u8fd9\u65f6\u540e\u7eed\u6d3b\u8dc3\u7684\u53e5\u67c4\u5c31\u4f1a\u5199\u5165<code>ovflist<\/code>\u800c\u4e0d\u662f<code>rdllist<\/code><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/ep_ovflist.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"1975\" height=\"784\" data-original=\"https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/ep_ovflist.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-515\"  sizes=\"auto, (max-width: 1975px) 100vw, 1975px\" \/><\/div><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">2. struct epitem<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u6bcf\u5f53\u6211\u4eec\u8c03\u7528<code>epoll_ctl<\/code>\u589e\u52a0\u4e00\u4e2a<code>fd<\/code>\u65f6\uff0c\u5185\u6838\u5c31\u4f1a\u4e3a\u6211\u4eec\u521b\u5efa\u51fa\u4e00\u4e2a<code>epitem<\/code>\u5b9e\u4f8b\uff0c\u5e76\u4e14\u628a\u8fd9\u4e2a\u5b9e\u4f8b\u4f5c\u4e3a\u7ea2\u9ed1\u6811\u7684\u4e00\u4e2a\u5b50\u8282\u70b9\uff0c\u589e\u52a0\u5230<code>eventpoll<\/code>\u7ed3\u6784\u4f53\u4e2d\u7684\u7ea2\u9ed1\u6811\u4e2d\uff0c\u5bf9\u5e94\u7684\u5b57\u6bb5\u662f<code>rbr<\/code>\u3002\u8fd9\u4e4b\u540e\uff0c\u67e5\u627e\u6bcf\u4e00\u4e2a<code>fd<\/code>\u4e0a\u662f\u5426\u6709\u4e8b\u4ef6\u53d1\u751f\u90fd\u662f\u901a\u8fc7\u7ea2\u9ed1\u6811\u4e0a\u7684<code>epitem<\/code>\u6765\u64cd\u4f5c<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u9664\u6ce8\u91ca\u5916\uff0c\u6240\u6709\u4ee3\u7801\u5747\u672a\u5220\u6539<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ linux-5.4\/fs\/eventpoll.c\n\/*\n * Each file descriptor added to the eventpoll interface will\n * have an entry of this type linked to the \"rbr\" RB tree.\n * Avoid increasing the size of this struct, there can be many thousands\n * of these on a server and we do not want this to take another cache line.\n *\/\nstruct epitem {\n    union {\n        \/* \u7ea2\u9ed1\u6811\u8282\u70b9\u5c06\u6b64\u7ed3\u6784\u94fe\u63a5\u5230eventpoll\u7ea2\u9ed1\u6811 *\/\n        struct rb_node rbn;\n        \/* RCU\u5934\u90e8\uff0c\u7528\u4e8e\u91ca\u653estruct epitem *\/\n        struct rcu_head rcu;\n    };\n\n    \/**\n     * \u8fd9\u91cc\u4f7f\u7528\u5185\u6838\u516c\u5171\u7684\u53cc\u5411\u94fe\u8868\u7ed3\u6784\u4fbf\u4e8e\u964d\u4f4e\u4fee\u6539\u65f6\u7684\u5f00\u9500\uff0c\u5b9e\u9645\u4e0a\u8fd9\u53ea\u662f\u4e00\u4e2a\u8282\u70b9\u6307\u9488\uff0c\u800c\u4e0d\u662f\u6574\u6761\u94fe\u8868\n     * \u7528\u4e8e\u5c06\u6b64\u7ed3\u6784\u4f53\u94fe\u63a5\u5230eventpoll-&gt;rdllist\u5c31\u7eea\u5217\u8868\u7684\u5217\u8868\u5934\n     *\/\n    struct list_head rdllink;\n\n    \/* \u534f\u540cstruct eventpoll\u7ed3\u6784\u4f53\u4e2d\u7684ovflist\u5b57\u6bb5\uff0c\u5171\u540c\u7ef4\u62a4\u8fd9\u4e2a\u5355\u94fe\u8868\u94fe *\/\n    struct epitem *next;\n\n    \/* \u88ab\u76d1\u89c6\u7684struct file *\u548cint fd *\/\n    struct epoll_filefd ffd;\n\n    \/* \u8868\u793a\u5f53\u524d\u6302\u7740\u7684\u6d3b\u8dc3\u7b49\u5f85\u961f\u5217\u9879\u6570\u91cf\uff0c\u7528\u4e8e\u6ce8\u518c\/\u6ce8\u9500 pollwait \u65f6\u7ef4\u62a4 *\/\n    int nwait;\n\n    \/** \n     * \u6bcf\u4e2a\u88abpoll\u7684\u6587\u4ef6\u53ef\u80fd\u6709\u591a\u5904wait queue head\u3002epoll\u901a\u8fc7 struct eppoll_entry\u628a\u81ea\u5df1\u6302\u5230\u76ee\u6807\u6587\u4ef6\u7684poll\u7b49\u5f85\u961f\u5217\u4e0a\n     * \u8fd9\u4e9beppoll_entry\u901a\u8fc7llink\u6302\u5728epi-&gt;pwqlist\u4e0a\n     *\/\n    struct list_head pwqlist;\n\n    \/* \u5f53\u524depollitem\u6240\u5c5e\u7684eventpoll *\/\n    struct eventpoll *ep;\n\n    \/* \u5217\u8868\u5934\u6587\u4ef6\uff0c\u7528\u4e8e\u5c06\u8be5\u9879\u94fe\u63a5\u5230\"struct file\"\u7684\u9879\u5217\u8868 *\/ \n    struct list_head fllink;\n\n    \/* \u8bbe\u7f6eEPOLLWAKEUP\u6807\u5fd7\u65f6\u4f7f\u7528\u7684\u5524\u9192\u6e90,\u7535\u6e90\u7ba1\u7406\u4f7f\u7528 *\/\n    struct wakeup_source __rcu *ws;\n\n    \/* \u7528\u6237\u4f20\u5165\u7684\u5174\u8da3\u4f4d(events mask)\u4ee5\u53cadata *\/\n    struct epoll_event event;\n};<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6838\u5fc3\u601d\u60f3<\/strong><br><code>struct epitem<\/code>\u7ed3\u6784\u4f53\u662f\u7528\u6765\u7ba1\u7406<code>epoll_ctl<\/code>\u76d1\u542c\u7684\u5b9e\u4f8b\u7684\u6570\u636e\u7ed3\u6784\uff0c<code>struct epitem<\/code>\u7ed3\u6784\u4f53\u53ef\u80fd<strong>\u540c\u65f6\u5b58\u5728\u6570\u767e\u4e07\u4e2a<\/strong>\uff0c\u4e3a\u4e86\u589e\u52a0\u7ba1\u7406\u6548\u7387\u4f7f\u7528\u4e86\u7ea2\u9ed1\u6811\u6765\u7ba1\u7406\u3002\u8fd9\u4e2a\u7ed3\u6784\u4f53\u88ab\u8bbe\u8ba1\u7684\u5c3d\u53ef\u80fd\u5c11\u7684\u5360\u7528\u5185\u5bb9\uff0c\u540c\u65f6\u4f7f\u7528<code>union<\/code>\u548c<code>__packed<\/code>\u6765\u8fdb\u4e00\u6b65\u4f18\u5316<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u9700\u8981\u7279\u522b\u5173\u6ce8\u7684\u662f<code>pwqlist<\/code>\u5b58\u50a8\u7b49\u5f85\u961f\u5217\u76f8\u5173\u4fe1\u606f\uff0c<code>event<\/code>\u5b58\u50a8\u7528\u6237\u4f20\u5165\u5f85\u76d1\u542c\u7684\u53e5\u67c4\u7684\u6570\u636e<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/struct_epitem-scaled.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"2488\" height=\"2560\" data-original=\"https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/struct_epitem-scaled.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-538\"  sizes=\"auto, (max-width: 2488px) 100vw, 2488px\" \/><\/div><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">1) epitem-&gt;ffd-&gt;file\u548ceventpoll-&gt;file<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\"><code>epitem-&gt;ffd-&gt;file<\/code>\u548c<code>eventpoll-&gt;file<\/code>\u90fd\u662f<code>struct file *<\/code>\u7c7b\u578b\u7684\u6570\u636e\uff0c\u4f46\u662f\u4e8c\u8005\u6307\u5411\u4e0d\u540c\u5185\u5b58\u5730\u5740<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>epitem-&gt;ffd-&gt;file\uff1a<\/strong>\u6307\u5411\u7684\u662f\u7528\u6237\u76d1\u542c\u7684\u53e5\u67c4\u5bf9\u5e94<code>fille<\/code>\uff0c\u662f\u901a\u8fc7<code>fdget(fd)<\/code>\u67e5\u627e\u7684<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>eventpoll-&gt;file\uff1a<\/strong>\u6307\u5411\u7684\u662f\u5f53\u524d<code>epoll<\/code>\u63cf\u8ff0\u7b26\u5bf9\u5e94\u7684<code>eventpoll<\/code>\u6587\u4ef6<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">2) rdllist &amp; rdllink\u548covflist &amp; next\u53cc\u94fe\u8868<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\"><code>rdllist &amp; rdllink<\/code>\u5bf9\u5e94<code>epoll<\/code>\u4e2d\u7684\u5c31\u7eea\u5217\u8868\uff0c<code>ovflist &amp; next<\/code>\u5bf9\u5e94\u7684\u5219\u662f<code>epoll<\/code>\u4e2d\u7684\u65e0\u9501\u7f13\u5b58\u6ea2\u51fa\u94fe\u8868<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>struct epitem\u4e2d\u5b58\u50a8\u7684\u662f\u94fe\u8868\u7684\u8282\u70b9\uff0c\u94fe\u8868\u771f\u6b63\u7684\u5934\u5728struct eventpoll\u4e2d<\/strong><br>\u5728\u7528\u6237\u8c03\u7528<code>epoll_ctl(EPOLL_CTL_ADD)<\/code>\u65f6\u5c31\u4f1a\u5c06<code>struct epoll_event<\/code>\u7c7b\u578b\u7684\u7ed3\u6784\u4f20\u5165\u5185\u6838\uff0c<code>epoll<\/code>\u6a21\u5757\u4f1a\u5c06\u5b83\u653e\u5728\u7ea2\u9ed1\u6811\u4e2d\u7ba1\u7406\u5b58\u50a8\uff0c\u5e76\u4e14\u5c06<code>ep_poll_callback<\/code>\u6ce8\u518c\u5728\u76d1\u542c\u7684\u53e5\u67c4\u8d44\u6e90\u7684\u5524\u9192\u961f\u5217\u4e2d\uff0c\u5f53\u6709\u53e5\u67c4\u6d3b\u8dc3\u5c31\u4f1a\u89e6\u53d1\u56de\u8c03\u3002<code>ep_poll_callback<\/code>\u4e2d\u4f1a\u628a\u6d3b\u8dc3\u7684\u53e5\u67c4\u5bf9\u5e94\u7684\u7ea2\u9ed1\u6811\u8282\u70b9\uff0c\u6dfb\u52a0\u5728\u5408\u9002\u7684\u961f\u5217\u5c3e\u90e8<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u8fd9\u79cd\u6d3b\u8dc3\u662f\u4e0d\u53ef\u9884\u6d4b\u968f\u673a\u7684\uff0c\u6240\u4ee5\u7ea2\u9ed1\u6811\u4e2d\u4efb\u4f55\u4e00\u4e2a\u8282\u70b9\u6709\u5bf9\u5e94\u7684\u53e5\u67c4\u90fd\u53ef\u80fd\u5728\u4e0b\u4e00\u523b\u6d3b\u8dc3\uff0c\u94fe\u8868\u4f1a\u50cf\u4e24\u6761\u7ebf\u4e00\u6837\u5728\u6811\u4e2d\u4e32\u8054\u5176\u4e2d\u7684\u8282\u70b9<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/struct_epitem_\u53cc\u94fe\u8868-scaled.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"1749\" data-original=\"https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/struct_epitem_\u53cc\u94fe\u8868-scaled.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-524\"  sizes=\"auto, (max-width: 2560px) 100vw, 2560px\" \/><\/div><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">3. struct eppoll_entry<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u6bcf\u6b21\u5f53\u4e00\u4e2a<code>fd<\/code>\u5173\u8054\u5230\u4e00\u4e2a<code>epoll<\/code>\u5b9e\u4f8b\uff0c\u5c31\u4f1a\u6709\u4e00\u4e2a<code>eppoll_entry<\/code>\u4ea7\u751f\uff0c\u7528\u4e8e\u8f6e\u8be2\u94a9\u5b50\u4f7f\u7528\u7684\u7b49\u5f85\u7ed3\u6784<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u9664\u6ce8\u91ca\u5916\uff0c\u6240\u6709\u4ee3\u7801\u5747\u672a\u5220\u6539<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ linux-5.4\/fs\/eventpoll.c\n\/* Wait structure used by the poll hooks *\/\nstruct eppoll_entry\n{\n    \/* \u628a\u672ceppoll_entry\u4e32\u8fdb\u6240\u5c5eepitem\u7684pwqlist *\/\n    struct list_head llink;\n\n    \/* \u6240\u5c5eepitem\u7ed3\u6784\u4f53\u7684\u5730\u5740 *\/\n    struct epitem *base;\n\n    \/* \u771f\u6b63\u6302\u5728\u9a71\u52a8\/\u5b50\u7cfb\u7edf whead \u4e0a\u7684\u7b49\u5f85\u961f\u5217\u9879\uff1b\u5176\u5524\u9192\u51fd\u6570\u88ab\u8bbe\u4e3a ep_poll_callback *\/\n    wait_queue_entry_t wait;\n\n    \/* \u8bb0\u5f55 wait \u88ab\u52a0\u5230\u4e86\u54ea\u4e2a wait_queue_head_t *\/\n    wait_queue_head_t *whead;\n};<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/struct-eppoll_entry.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"618\" height=\"302\" data-original=\"https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/struct-eppoll_entry.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-522\"  sizes=\"auto, (max-width: 618px) 100vw, 618px\" \/><\/div><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">\u516d\u3001epoll\u57fa\u672c\u6d41\u7a0b<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1. epoll\u57fa\u672c\u6d41\u7a0b\u56fe<\/h3>\n\n\n\n<figure class=\"wp-block-image size-full\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/epoll\u4e3b\u6d41\u7a0b-scaled.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"1880\" data-original=\"https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/epoll\u4e3b\u6d41\u7a0b-scaled.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-521\"  sizes=\"auto, (max-width: 2560px) 100vw, 2560px\" \/><\/div><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">2. \u521b\u5efaepoll\u5b9e\u4f8b<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u5185\u6838\u5bf9\u4e8e\u65b0\u5efa\u4e00\u4e2a<code>epoll<\/code>\u5b9e\u4f8b\u63d0\u4f9b\u4e86\u4e24\u4e2a\u5916\u90e8\u63a5\u53e3<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>epoll_create\u63a5\u53e3\u5df2\u5e9f\u5f03<\/strong>\uff0c<code>epoll_create1<\/code>\u63a5\u53e3\u53c2\u6570\u901a\u5e38\u4f7f\u7528<code>0<\/code>\uff0c\u4e5f\u53ef\u4f7f\u7528<code>EPOLL_CLOEXEC<\/code>\u4e3a\u65b0\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26\u8bbe\u7f6e\u201c\u6267\u884c\u65f6\u5173\u95ed\u201d\u6807\u5fd7\uff08<code>FD_CLOEXEC<\/code>\uff09<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u9664\u6ce8\u91ca\u5916\uff0c\u6240\u6709\u4ee3\u7801\u5747\u672a\u5220\u6539<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ linux\/linux-5.4\/fs\/eventpoll.c\nSYSCALL_DEFINE1(epoll_create1, int, flags)\n{\n    return do_epoll_create(flags);\n}\n\n\/\/ linux\/linux-5.4\/fs\/eventpoll.c:\u5df2\u5e9f\u5f03\nSYSCALL_DEFINE1(epoll_create, int, size)\n{\n    if (size &lt;= 0)\n        return -EINVAL;\n\n    return do_epoll_create(0);\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>do_epoll_create\u51fd\u6570<\/strong><br>\u521b\u5efa\u65b0\u7684<code>epoll<\/code>\u8282\u70b9<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6838\u5fc3\u903b\u8f91\u5982\u4e0b<\/strong><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u4e0b\u6587\u4ee3\u7801\u5df2\u683c\u5f0f\u5316\u5904\u7406\uff0c\u5e76\u9002\u5f53\u7b80\u5316\u53ea\u4fdd\u7559\u6838\u5fc3\u903b\u8f91<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ linux-5.4\/fs\/anon_inodes.c\n\/**\n * anon_inode_getfile-\u901a\u8fc7\u8fde\u63a5\u4e00\u4e2a\u533f\u540dinode\u548c\u4e00\u4e2a\u63cf\u8ff0\u6587\u4ef6\u201c\u7c7b\u201d\u7684dentry\u6765\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u6587\u4ef6\u5b9e\u4f8b\n * @name:\u65b0\u6587\u4ef6\u7684\u201c\u7c7b\u201d\u7684\u540d\u79f0\n * @fops:\u6587\u4ef6\u64cd\u4f5c\u7684\u65b0\u6587\u4ef6\n * @priv:\u65b0\u6587\u4ef6\u7684\u79c1\u6709\u6570\u636e(\u5c06\u662f\u6587\u4ef6\u7684private_data)\n * @flags:\u6253\u5f00\u6587\u4ef6\u7684\u884c\u4e3a\u548c\u5c5e\u6027\n *\n * \u901a\u8fc7\u5c06\u4e00\u4e2a\u6587\u4ef6\u6302\u63a5\u5728\u5355\u4e2a\u7d22\u5f15\u8282\u70b9\u4e0a\u6765\u521b\u5efa\u4e00\u4e2a\u65b0\u6587\u4ef6\u3002\u8fd9\u5bf9\u4e8e\u4e0d\u9700\u8981\u5b8c\u6574inode\u5c31\u53ef\u4ee5\u6b63\u786e\u64cd\u4f5c\u7684\u6587\u4ef6\u5f88\u6709\u7528\u3002\n * \u4f7f\u7528anon_inode_getfile()\u521b\u5efa\u7684\u6240\u6709\u6587\u4ef6\u5c06\u5171\u4eab\u4e00\u4e2ainode\uff0c\u4ece\u800c\u8282\u7701\u5185\u5b58\u5e76\u907f\u514d\u6587\u4ef6\/inode\/dentry\u8bbe\u7f6e\u7684\u4ee3\u7801\u91cd\u590d\u3002\u8fd4\u56de\u65b0\u521b\u5efa\u7684\u6587\u4ef6*\u6216\u9519\u8bef\u6307\u9488\u3002\n *\/\nstruct file *anon_inode_getfile(const char *name, const struct file_operations *fops, void *priv, int flags);\n\n\/\/ linux-5.4\/fs\/eventpoll.c\n\/* File callbacks that implement the eventpoll file behaviour *\/\nstatic const struct file_operations eventpoll_fops = {\n    .show_fdinfo    = ep_show_fdinfo,\n    .release        = ep_eventpoll_release,\n    .poll           = ep_eventpoll_poll,\n    .llseek         = noop_llseek,\n};\n\n\/\/ linux-5.4\/fs\/eventpoll.c\nstatic int ep_alloc(struct eventpoll **pep)\n{\n    struct user_struct *user;\n    struct eventpoll *ep;\n\n    \/* \u8fd4\u56de\u5f53\u524d\u8fdb\u7a0b\u7684\u7528\u6237ID *\/\n    user = get_current_user();\n    ep = kzalloc(sizeof(*ep), GFP_KERNEL);\n\n    \/* \u521d\u59cb\u5316\u4e92\u65a5\u9501 *\/\n    mutex_init(&amp;ep-&gt;mtx);\n    \/* \u521d\u59cb\u5316\u8bfb\u5199\u9501 *\/\n    rwlock_init(&amp;ep-&gt;lock);\n    init_waitqueue_head(&amp;ep-&gt;wq);\n    init_waitqueue_head(&amp;ep-&gt;poll_wait);\n    INIT_LIST_HEAD(&amp;ep-&gt;rdllist);\n    ep-&gt;rbr = RB_ROOT_CACHED;\n    ep-&gt;ovflist = EP_UNACTIVE_PTR;\n    ep-&gt;user = user;\n\n    *pep = ep;\n\n    return 0;\n}\n\nstatic int do_epoll_create(int flags)\n{\n    int error, fd;\n    struct eventpoll *ep = NULL;\n    struct file *file;\n\n    ep_alloc(&amp;ep);\n\n    \/* \u83b7\u53d6\u4e00\u4e2a\u53ef\u8bfb\u53ef\u5199\u7684\u672a\u88ab\u4f7f\u7528\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26 *\/\n    fd = get_unused_fd_flags(O_RDWR | (flags &amp; O_CLOEXEC));\n    \/* \u521b\u5efa\u4e00\u4e2a\u533f\u540d\u7684inode\u8282\u70b9 *\/\n    file = anon_inode_getfile(\"&#91;eventpoll]\", &amp;eventpoll_fops, ep, O_RDWR | (flags &amp; O_CLOEXEC));\n\n    \/* \u5c06\u8fd9\u4e2a\u65b0\u7684file\u6ce8\u518c\u5230\u5bf9\u5e94\u7684eventpoll\u4e2d *\/\n    ep-&gt;file = file;\n    \/* \u628afile\u6307\u9488\u5199\u8fdb\u5f53\u524d\u8fdb\u7a0bfd\u5bf9\u5e94\u69fd\u4f4d *\/\n    fd_install(fd, file);\n\n    return fd;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6838\u5fc3\u601d\u60f3<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u521b\u5efainode\u8282\u70b9<\/strong> \u521b\u5efa\u4e00\u4e2a\u533f\u540d\u7684<code>inode<\/code>\u8282\u70b9\uff0c\u8fd9\u4e2a\u6587\u4ef6\u5bf9\u8c61\u901a\u5e38\u4e0d\u5bf9\u5e94\u4e8e\u5b9e\u9645\u7684\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u4efb\u4f55\u6587\u4ef6\uff0c\u56e0\u6b64\u88ab\u79f0\u4e3a\u533f\u540d<code>inode<\/code>\u3002\u5b83\u88ab\u7528\u4f5c<code>epoll<\/code>\u5b9e\u4f8b\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26\uff0c\u901a\u8fc7\u8fd9\u4e2a\u6587\u4ef6\u63cf\u8ff0\u7b26\uff0c\u7528\u6237\u7a7a\u95f4\u7a0b\u5e8f\u53ef\u4ee5\u5bf9<code>epoll<\/code>\u5b9e\u4f8b\u8fdb\u884c<code>I\/O<\/code>\u64cd\u4f5c\u3002\u5e76\u8fd4\u56de\u4e0e\u4e4b\u5173\u8054\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26<\/li>\n\n\n\n<li><strong>\u4f7f\u7528anon_inode_getfile\u521b\u5efa\u533f\u540dinode\u8282\u70b9<\/strong>\uff0c\u6b64\u5904\u4e0d\u8be6\u7ec6\u5c55\u5f00\u5b9e\u73b0\u4ee3\u7801\uff0c\u4ec5\u5217\u51fa\u51fd\u6570\u8c03\u7528\u6808<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>     \/* \u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u533f\u540dinode *\/\n   -&gt;anon_inode_getfile(const char *name, const struct file_operations *fops, \n                         void *priv, int flags)\n         \/* \u57fa\u4e8e\u4f2a\u6587\u4ef6\u7cfb\u7edf anon_inode_mnt\uff08\u533f\u540d inode \u6302\u8f7d\u70b9\uff09+ \u5171\u4eab inode \u5206\u914d\u4e00\u4e2a\u65b0\u7684 struct file *\/\n       -&gt;alloc_file_pseudo(struct inode *inode, struct vfsmount *mnt, const char *name, int flags,\n                            const struct file_operations *fops)\n           \/* \u5c06\u65b0\u5efa\u7684file-&gt;f_op\u8d4b\u503c\u4e3a\u5165\u53c2eventpoll_fops *\/\n           -&gt;alloc_file(const struct path *path, int flags, const struct file_operations *fop)\n               \/* \u521b\u5efa\u4e00\u4e2a\u7a7a\u7684file\u5bf9\u8c61\uff0c\u8bbe\u7f6e\u88ab\u521b\u5efa\u6587\u4ef6\u7684\u72b6\u6001\u548c\u5c5e\u6027\u4e3aflags *\/\n               -&gt;alloc_empty_file(int flags, const struct cred *cred)\n         \/* \u5c06\u65b0\u5efa\u7684file-&gt;private_data\u8d4b\u503c\u4e3apriv *\/\n       -&gt;file-&gt;private_data = priv<\/code><\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u4f7f\u7528fd_install\u5c06\u65b0\u521b\u5efa\u7684inode\u8282\u70b9\u63d2\u5165\u5f53\u524d\u8fdb\u7a0b\u7684\u6587\u4ef6\u6570\u7ec4\u4e2d<\/strong><\/li>\n<\/ol>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u4e0b\u6587\u4ee3\u7801\u5df2\u683c\u5f0f\u5316\u5904\u7406\uff0c\u5e76\u9002\u5f53\u7b80\u5316\u53ea\u4fdd\u7559\u6838\u5fc3\u903b\u8f91<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>   \/\/ linux-5.4\/fs\/file.c\n   void fd_install(unsigned int fd, struct file *file)\n   {\n       \/* current-&gt;files\u662f\u6307\u5411\u5f53\u524d\u8fdb\u7a0b\u6587\u4ef6\u63cf\u8ff0\u7b26\u8868\u7684\u6307\u9488 *\/\n       __fd_install(current-&gt;files, fd, file);\n   }\n\n   \/**\n    * fd:\u6587\u4ef6\u63cf\u8ff0\u7b26\n    * file:\u65b0\u5efa\u7684inode\u8282\u70b9\n    * struct fdtable\uff1a\u5185\u6838\u4e2d\u7528\u6765\u7ba1\u7406\u6587\u4ef6\u63cf\u8ff0\u7b26\u7684\u6570\u636e\u7ed3\u6784\n    * fdt-&gt;fd\uff1a\u5b58\u50a8file\u7ed3\u6784\u4f53\u7684\u6570\u7ec4\uff1a\n    *\/\n   void __fd_install(struct files_struct *files, unsigned int fd, struct file *file)\n   {\n       struct fdtable *fdt;\n       fdt = files_fdtable(files);\n       rcu_assign_pointer(fdt-&gt;fd&#91;fd], file);\n   }<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u6b64\u5904\u5c06\u65b0\u5efa\u7684<code>file<\/code>\u8282\u70b9\u63d2\u5165\uff0c\u5bf9\u5e94\u5f53\u524d\u7684\u8fdb\u7a0b\u6587\u4ef6\u6570\u7ec4\u4e2d\uff0c\u7528\u4e8e\u540e\u7eed\u5185\u6838\u7ba1\u7406<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/do_epoll_create\u6d41\u7a0b-scaled.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"771\" data-original=\"https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/do_epoll_create\u6d41\u7a0b-scaled.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-511\"  sizes=\"auto, (max-width: 2560px) 100vw, 2560px\" \/><\/div><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">3. \u4fee\u6539\u76d1\u542c\u53e5\u67c4<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>epoll_ctl\u51fd\u6570<\/strong><br>\u7528\u4e8e\u5411<code>epoll<\/code>\u5b9e\u4f8b\u4e2d<strong>\u6dfb\u52a0\u3001\u4fee\u6539\u6216\u5220\u9664<\/strong>\u611f\u5174\u8da3\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26\uff08<code>socket<\/code>\u3001\u6587\u4ef6\u7b49\uff09\u53ca\u5176\u5173\u6ce8\u7684\u4e8b\u4ef6<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6838\u5fc3\u903b\u8f91\u5982\u4e0b<\/strong><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u4e0b\u6587\u4ee3\u7801\u5df2\u683c\u5f0f\u5316\u5904\u7406\uff0c\u5e76\u9002\u5f53\u7b80\u5316\u53ea\u4fdd\u7559\u6838\u5fc3\u903b\u8f91<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ linux-5.4\/fs\/eventpoll.c\n\/*\n * @epfd: epool_create\u521b\u5efa\u7684\u7528\u4e8eeventpoll\u7684fd\n * @op: \u63a7\u5236\u7684\u547d\u4ee4\u7c7b\u578b\n * EPOLL_CTL_ADD\uff1a\u6dfb\u52a0\u4e00\u4e2a\u65b0\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26\u548c\u5176\u5173\u6ce8\u7684\u4e8b\u4ef6\u5230 epoll \u5b9e\u4f8b\u4e2d\u3002\n * EPOLL_CTL_MOD\uff1a\u4fee\u6539\u4e00\u4e2a\u5df2\u7ecf\u5b58\u5728\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26\u5173\u6ce8\u7684\u4e8b\u4ef6\u3002\n * EPOLL_CTL_DEL\uff1a\u4ece epoll \u5b9e\u4f8b\u4e2d\u5220\u9664\u4e00\u4e2a\u6587\u4ef6\u63cf\u8ff0\u7b26\u3002\n *\n * @fd: \u8981\u64cd\u4f5c\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26\n * @event:\u4e0efd\u76f8\u5173\u7684\u5bf9\u8c61,\u63cf\u8ff0\u4e86\u8981\u6dfb\u52a0\u3001\u4fee\u6539\u6216\u5220\u9664\u7684\u4e8b\u4ef6\u3002\n *\/\nSYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,\n        struct epoll_event __user *, event)\n{\n    int error;\n    struct fd f, tf;\n    struct eventpoll *ep;\n    struct epitem *epi;\n    struct epoll_event epds;\n    struct eventpoll *tep = NULL;\n\n    error = -EFAULT;\n    \/* \u4ece\u7528\u6237\u7a7a\u95f4\u83b7\u53d6epoll_event\u7ed3\u6784\u4f53\u6570\u636e *\/\n    copy_from_user(&amp;epds, event, sizeof(struct epoll_event));\n\n    \/* \u83b7\u53d6epoll_create1\u521b\u5efa\u7684epoll_event\u5b9e\u4f8b\u5bf9\u5e94struct file *\u7ed3\u6784\u4f53 *\/\n    f = fdget(epfd);\n\n    \/* \u83b7\u53d6\u8981\u76d1\u542c\u7684\u53e5\u67c4\u5bf9\u5e94\u7684struct file *\u7ed3\u6784\u4f53 *\/\n    tf = fdget(fd);\n\n    \/* \u4e0d\u5141\u8bb8\u81ea\u5df1\u76d1\u542c\u81ea\u5df1\uff0c\u540c\u65f6\u68c0\u67e5tf.file\u548cf.file\u662f\u5426\u652f\u6301poll\u64cd\u4f5c *\/\n    if (f.file == tf.file || !is_file_epoll(f.file) || !file_can_poll(tf.file))\n        goto error_tgt_fput;\n\n    ep = f.file-&gt;private_data;\n\n    \/**\n     * \u7b14\u8005\u6ce8\uff1a\u6b64\u5904\u6781\u5927\u7701\u7565\uff0c\u53ea\u4fdd\u7559\u6838\u5fc3\u903b\u8f91\n     * \u68c0\u67e5\u662f\u5426\u5b58\u5728\n     * 1. \u591a\u5c42\u5d4c\u5957epoll\n     * 2. \u591a\u8fdb\u7a0b\u7684epoll\u76d1\u542c\u4e4b\u95f4\u662f\u5426\u5b58\u5728\u73af\u8def\n     * 3. \u8fc7\u6df1\u7684wakeup\u8def\u5f84 \n     *\/\n    if (ep_loop_check(ep, tf.file) != 0) {\n        clear_tfile_check_list();\n        goto error_tgt_fput;\n    }\n\n    \/* \u5728\u7ea2\u9ed1\u6811\u4e2d\u67e5\u627e\u8981\u76d1\u542c\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26\u5bf9\u5e94\u7684epitem\u7ed3\u6784\u4f53\uff0c\u5982\u679c\u5b58\u5728\u5219\u8fd4\u56de\u6307\u5411\u8be5\u7ed3\u6784\u4f53\u7684\u6307\u9488\uff0c\u5426\u5219\u8fd4\u56deNULL *\/\n    epi = ep_find(ep, tf.file, fd);\n\n    error = -EINVAL;\n    switch (op) {\n    case EPOLL_CTL_ADD:\n        if (!epi) {\n            epds.events |= EPOLLERR | EPOLLHUP;\n            error = ep_insert(ep, &amp;epds, tf.file, fd);\n        } else\n            error = -EEXIST;\n        break;\n    case EPOLL_CTL_DEL:\n        if (epi)\n            error = ep_remove(ep, epi);\n        else\n            error = -ENOENT;\n        break;\n    case EPOLL_CTL_MOD:\n        if (epi) {\n            if (!(epi-&gt;event.events &amp; EPOLLEXCLUSIVE)) {\n                epds.events |= EPOLLERR | EPOLLHUP;\n                error = ep_modify(ep, epi, &amp;epds);\n            }\n        } else\n            error = -ENOENT;\n        break;\n    }\n\nerror_tgt_fput:\n    fdput(tf);\n    fdput(f);\n\n    return error;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6838\u5fc3\u601d\u60f3<\/strong><br><code>epoll_ctl<\/code>\u63a5\u53e3\u4ece\u7528\u6237\u6001\u4f20\u5165\u7684\u914d\u7f6e\u597d\u7684<code>struct epoll_event<\/code>\u7ed3\u6784\u4f53\u548c\u5bf9\u5e94\u7684<code>epoll_create1<\/code>\u521b\u5efa\u7684<code>epoll_event<\/code>\u5b9e\u4f8b<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u901a\u8fc7<code>fdget<\/code>\u63a5\u53e3\u83b7\u53d6\u53e5\u67c4\u5bf9\u5e94\u7684\u8fdb\u7a0b\u63cf\u8ff0\u7b26<code>struct file<\/code>\uff0c\u68c0\u67e5\u4e86\u662f\u5426\u652f\u6301<code>poll<\/code>\u64cd\u4f5c<\/li>\n\n\n\n<li>\u68c0\u67e5\u662f\u5426\u5b58\u5728\u5d4c\u5957<code>epoll<\/code>\u3001\u591a\u8fdb\u7a0b\u4e4b\u95f4\u662f\u5426\u5b58\u5728\u73af\u8def\u3001\u8fc7\u6df1\u7684<code>wakeup<\/code>\u8def\u5f84\u7b49\u60c5\u51b5<\/li>\n\n\n\n<li>\u662f\u5426\u5728\u7ea2\u9ed1\u6811\u4e0a\u5df2\u5b58\u5728<\/li>\n\n\n\n<li>\u6309\u7167\u64cd\u4f5c\u7c7b\u578b\u8fdb\u884c\u5bf9\u5e94\u7684\u589e\u5220\u6539\u64cd\u4f5c<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image size-full\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/\u7ea2\u9ed1\u6811\u64cd\u4f5c\u63a5\u53e3.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"1663\" height=\"1528\" data-original=\"https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/\u7ea2\u9ed1\u6811\u64cd\u4f5c\u63a5\u53e3.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-539\"  sizes=\"auto, (max-width: 1663px) 100vw, 1663px\" \/><\/div><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">4. \u7b49\u5f85\u53e5\u67c4\u6d3b\u8dc3<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>epoll_wait\u51fd\u6570<\/strong><br><code>epoll_ctl(EPOLL_CTL_ADD)<\/code>\u5df2\u7ecf\u5c06\u53e5\u67c4\u6dfb\u52a0\u5230\u5185\u6838\u7684\u7b49\u5f85\u961f\u5217\u4e2d\u4e86\uff0c<code>epoll_wait<\/code>\u5219\u7528\u6237\u6001\u662f\u83b7\u53d6\u53e5\u67c4\u6d3b\u8dc3\u65f6\u7684\u901a\u77e5<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6838\u5fc3\u903b\u8f91\u5982\u4e0b<\/strong><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u4e0b\u6587\u4ee3\u7801\u5df2\u683c\u5f0f\u5316\u5904\u7406\uff0c\u5e76\u9002\u5f53\u7b80\u5316\u53ea\u4fdd\u7559\u6838\u5fc3\u903b\u8f91<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ linux-5.4\/fs\/eventpoll.c\nSYSCALL_DEFINE4(epoll_wait, int, epfd, struct epoll_event __user *, events,\n                int, maxevents, int, timeout)\n{\n    return do_epoll_wait(epfd, events, maxevents, timeout);\n}\n\nstatic int do_epoll_wait(int epfd, struct epoll_event __user *events,\n                         int maxevents, int timeout)\n{\n    int error;\n    struct fd f;\n    struct eventpoll *ep;\n\n    f = fdget(epfd);\n\n    ep = f.file-&gt;private_data;\n    error = ep_poll(ep, events, maxevents, timeout);\n\n    fdput(f);\n    return error;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>ep_poll\u51fd\u6570<\/strong><br>\u8fd9\u4e2a\u51fd\u6570\u771f\u6b63\u5c06\u6267\u884c<code>epoll_wait<\/code>\u7684\u8fdb\u7a0b\u5e26\u5165\u7761\u7720\u72b6\u6001<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6838\u5fc3\u903b\u8f91\u5982\u4e0b<\/strong><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u4e0b\u6587\u4ee3\u7801\u5df2\u683c\u5f0f\u5316\u5904\u7406\uff0c\u5e76\u9002\u5f53\u7b80\u5316\u53ea\u4fdd\u7559\u6838\u5fc3\u903b\u8f91<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ linux-5.4\/fs\/eventpoll.c\n\/*\n * ep_poll - \u68c0\u7d22\u51c6\u5907\u597d\u7684\u4e8b\u4ef6\uff0c\u5e76\u5c06\u5b83\u4eec\u4f20\u9012\u5230\u8c03\u7528\u8005\u63d0\u4f9b\u7684\u4e8b\u4ef6\u7f13\u51b2\u533a\n *\n * @ep: \u6307\u5411eventpoll\u4e0a\u4e0b\u6587\u7684\u6307\u9488\n * @events: \u6307\u5411\u7528\u6237\u7a7a\u95f4\u7f13\u51b2\u533a\u7684\u6307\u9488\uff0c\u51c6\u5907\u597d\u7684\u4e8b\u4ef6\u5e94\u8be5\u5b58\u50a8\u5728\u8fd9\u91cc\n * @maxevents: \u8c03\u7528\u8005\u4e8b\u4ef6\u7f13\u51b2\u533a\u7684\u5927\u5c0f(\u4ee5\u4e8b\u4ef6\u6570\u91cf\u8868\u793a)\n * @timeout: \u51c6\u5907\u4e8b\u4ef6\u83b7\u53d6\u64cd\u4f5c\u7684\u6700\u5927\u8d85\u65f6\u65f6\u95f4\uff0c\u5355\u4f4d\u4e3a\u6beb\u79d2\u3002\u5982\u679c@timeout\u4e3a\u96f6\uff0c\u5219\u8be5\u51fd\u6570\u4e0d\u4f1a\u963b\u585e\n *              \u800c\u5982\u679c@timeout\u5c0f\u4e8e\u96f6\uff0c\u5219\u8be5\u51fd\u6570\u5c06\u963b\u585e\uff0c\u76f4\u5230\u81f3\u5c11\u68c0\u7d22\u5230\u4e00\u4e2a\u4e8b\u4ef6(\u6216\u53d1\u751f\u9519\u8bef)\n * @return: \u8fd4\u56de\u5df2\u83b7\u53d6\u7684\u5c31\u7eea\u4e8b\u4ef6\u7684\u6570\u91cf\uff0c\u6216\u8005\u5728\u51fa\u73b0\u9519\u8bef\u65f6\u8fd4\u56de\u9519\u8bef\u4ee3\u7801\u3002\n *\/\nstatic int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,\n           int maxevents, long timeout)\n{\n    int res = 0, eavail, timed_out = 0;\n    u64 slack = 0;\n    bool waiter = false;\n    wait_queue_entry_t wait;\n    ktime_t expires, *to = NULL;\n\n    lockdep_assert_irqs_enabled();\n\n    \/* \u65f6\u95f4\u5927\u4e8e0\u5219\u8ba1\u7b97\u7b49\u5f85\u65f6\u95f4 *\/\n    if (timeout &gt; 0) {\n        slack = select_estimate_accuracy(&amp;end_time);\n        *to = timespec64_to_ktime(end_time);\n    \/* \u65f6\u95f4\u5c0f\u4e8e0\u5219\u8fd9\u4e00\u6b21\u76f4\u63a5\u8df3\u8fc7\u7b49\u5f85\u8fc7\u7a0b *\/\n    } else if (timeout == 0) {\n        timed_out = 1;\n        \/* \u68c0\u67e5\u5f53\u524d\u5c31\u7eea\u4e8b\u4ef6 *\/\n        eavail = ep_events_available(ep);\n\n        goto send_events;\n    }\n\nfetch_events:\n    \/* \u5148\u6267\u884c\u5fd9\u7b49\u5f85 *\/\n    if (!ep_events_available(ep))\n        ep_busy_loop(ep, timed_out);\n\n    \/* \u68c0\u67e5\u5f53\u524d\u5c31\u7eea\u4e8b\u4ef6\uff0c\u5982\u679c\u6709\u5219\u76f4\u63a5\u8fd4\u56de\u5c31\u7eea\u4e8b\u4ef6 *\/\n    if (ep_events_available(ep))\n        goto send_events;\n\n    if (!waiter) {\n        waiter = true;\n         \/* \u521d\u59cb\u5316\u672c\u7ebf\u7a0b\u7b49\u5f85\u961f\u5217\uff0c\u628a\u672c\u7ebf\u7a0b\u767b\u8bb0\u5230epoll\u7684waitqueue  *\/\n        init_waitqueue_entry(&amp;wait, current);\n        __add_wait_queue_exclusive(&amp;ep-&gt;wq, &amp;wait);\n    }\n\n    for (;;) {\n        \/* \u5c06\u8fdb\u7a0b\u8bbe\u7f6e\u4e3a\u53ef\u4e2d\u65ad\u7761\u7720\u6001 *\/\n        set_current_state(TASK_INTERRUPTIBLE);\n        \/* \u5148\u68c0\u67e5\u81f4\u547d\u4fe1\u53f7\uff0c\u5982\u679c\u6709\u5219\u76f4\u63a5\u8fd4\u56de\u9519\u8bef *\/\n        if (fatal_signal_pending(current)) {\n            res = -EINTR;\n            break;\n        }\n\n        \/* \u518d\u68c0\u67e5\u5c31\u7eea\u4e8b\u4ef6\uff0c\u5982\u679c\u6709\u5219\u76f4\u63a5\u8fd4\u56de\u5c31\u7eea\u4e8b\u4ef6 *\/\n        eavail = ep_events_available(ep);\n        if (eavail)\n            break;\n\n        \/* \u6700\u540e\u68c0\u67e5\u666e\u901a\u4fe1\u53f7\uff0c\u5982\u679c\u6709\u5219\u76f4\u63a5\u8fd4\u56de\u9519\u8bef *\/\n        if (signal_pending(current)) {\n            res = -EINTR;\n            break;\n        }\n\n        \/* \u5982\u679c\u6709\u7b49\u5f85\u65f6\u95f4\u5219\u7ee7\u7eed\u7b49\u5f85\uff0c\u5426\u5219\u76f4\u63a5\u8fd4\u56de\u8d85\u65f6 *\/\n        if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS)) {\n            timed_out = 1;\n            break;\n        }\n    }\n\n    \/* \u5c06\u8fdb\u7a0b\u72b6\u6001\u8bbe\u7f6e\u4e3a\u8fd0\u884c\u6001 *\/\n    __set_current_state(TASK_RUNNING);\n\nsend_events:\n    \/**\n     * Try to transfer events to user space. In case we get 0 events and\n     * there's still timeout left over, we go trying again in search of\n     * more luck.\n     *\n     * \u5c3d\u529b\u5c06\u4e8b\u4ef6\u8f6c\u79fb\u5230\u7528\u6237\u7a7a\u95f4\u3002\u5018\u82e5\u6211\u4eec\u83b7\u53d6\u5230\u7684\u4e8b\u4ef6\u6570\u4e3a 0\uff0c\u800c\u5269\u4f59\u7684\u8d85\u65f6\u65f6\u95f4\u4ecd\u6709\u5269\u4f59\u7684\u8bdd\uff0c\u6211\u4eec\u5c31\u7ee7\u7eed\u5c1d\u8bd5\uff0c\u5e0c\u671b\u80fd\u83b7\u5f97\u66f4\u591a\u7684\u673a\u4f1a\u3002\n     *\/\n    if (!res &amp;&amp; eavail &amp;&amp;\n        !(res = ep_send_events(ep, events, maxevents)) &amp;&amp; !timed_out)\n        goto fetch_events;\n\n    \/* \u5982\u679c\u4e4b\u524d\u767b\u8bb0\u4e86\u7b49\u5f85\u961f\u5217\uff0c\u5219\u5c06\u672c\u7ebf\u7a0b\u4eceepoll\u7684waitqueue\u4e2d\u79fb\u9664 *\/\n    if (waiter) {\n        __remove_wait_queue(&amp;ep-&gt;wq, &amp;wait);\n    }\n\n    return res;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6838\u5fc3\u601d\u60f3<\/strong><br><code>ep_poll<\/code>\u51fd\u6570\u5bf9\u7528\u6237\u6001\u63d0\u4f9b\u4e86\u7075\u6d3b\u7684\u63a5\u53e3\uff0c\u81ea\u8eab\u5728\u9ad8\u5e76\u53d1\u7684\u573a\u666f\u4e0b\u4e5f\u6709\u4e13\u95e8\u7684\u4f18\u5316\u5904\u7406\uff0c<strong>\u6709\u56db\u79cd\u7406\u89e3\u89d2\u5ea6<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><code>time_out<\/code>\u5c0f\u4e8e<code>0<\/code>\u65f6\uff0c\u4e00\u76f4\u963b\u585e\u63a5\u53e3\u76f4\u5230\u76d1\u542c\u7684\u53e5\u67c4\u6709\u4efb\u4f55\u4e00\u4e2a\u6d3b\u8dc3<\/li>\n\n\n\n<li><code>time_out<\/code>\u7b49\u4e8e<code>0<\/code>\u65f6\uff0c\u8df3\u8fc7\u4e2d\u95f4\u6d41\u7a0b\u53ea\u505a\u67e5\u8be2\u52a8\u4f5c\uff0c\u8fd9\u65f6\u7528\u6237\u6001\u5c31\u662f\u53ea\u505a\u67e5\u8be2\u800c\u4e0d\u4f1a\u963b\u585e\u63a5\u53e3<\/li>\n\n\n\n<li><code>time_out<\/code>\u5927\u4e8e<code>0<\/code>\u65f6\uff0c\u76d1\u542c\u4e00\u4e2a\u6c38\u8fdc\u4e0d\u4f1a\u6d3b\u8dc3\u7684\u53e5\u67c4\uff0c\u8fd9\u65f6\u7528\u6237\u6001\u4f1a\u4e00\u76f4\u963b\u585e\u5728<code>epoll_wait<\/code>\u63a5\u53e3<code>time_out<\/code>\u65f6\u95f4\uff0c\u5e76\u4e14\u4e0d\u4f1a\u5360\u7528<code>CPU<\/code>\u8d44\u6e90<\/li>\n\n\n\n<li><code>time_out<\/code>\u5927\u4e8e<code>0<\/code>\u65f6\uff0c\u76d1\u542c\u4e00\u4e2a\u666e\u901a\u53e5\u67c4\u7684\u5e38\u89c4\u6d41\u7a0b<\/li>\n\n\n\n<li>\u6781\u9ad8\u5e76\u53d1\u4e0b\uff0c\u9000\u5316\u6210\u5fd9\u68c0\u6d4b\u7684\u72b6\u6001 \u5728\u6781\u9ad8\u7684\u5e76\u53d1\u4e0b\u53ef\u4ee5\u8ba4\u4e3a\uff0c<code>ep_busy_loop<\/code>\u6c38\u8fdc\u4f1a\u67e5\u8be2\u5230\u65b0\u7684\u5c31\u7eea\u4e8b\u4ef6\uff0c\u4f1a\u76f4\u63a5<code>goto<\/code>\u5230<code>send_events<\/code>\u6700\u540e\u3002\u540c\u65f6\u6c38\u8fdc\u4e5f\u4e0d\u53ef\u80fd\u53d1\u9001\u5b8c\u6240\u6709\u7684\u4e8b\u4ef6\uff0c\u53c8\u4f1a\u8df3\u8f6c\u56de<code>fetch_events<\/code>\uff0c\u91cd\u590d\u8fd9\u8f6e\u5faa\u73af\u3002\u8fd9\u79cd\u8bbe\u8ba1\u53ea\u5728\u4e00\u4e2a\u51fd\u6570\u5185\u90e8\uff0c\u4e0d\u4f9d\u8d56\u590d\u6742\u7684\u72b6\u6001\u673a\u3002\u5728\u9ad8\u5e76\u53d1\u4e0b\u7531\u4e8e\u53ea\u6267\u884c\u4e86\u5f88\u5c11\u7684\u4ee3\u7801\uff0c\u4f1a\u8282\u7ea6\u5927\u91cf\u7684<code>CPU<\/code>\u8d44\u6e90\uff0c\u5728\u7b2c\u5e76\u53d1\u65f6\u53c8\u4f1a\u81ea\u52a8\u5207\u6362\u56de\u6b63\u5e38\u6d41\u7a0b\uff0c\u8bbe\u8ba1\u6781\u4e3a\u7cbe\u5999<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">\u6700\u7ec8\u68c0\u6d4b\u5c31\u7eea\u4e8b\u4ef6\uff0c<strong>\u53d1\u9001\u5c31\u7eea\u4e8b\u4ef6\u5230\u7528\u6237\u6001\uff0c\u8fd9\u90e8\u5206\u7684\u5177\u4f53\u5b9e\u73b0\u89c1\u4e0b\u6587<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/ep_poll-2602x4096.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"2602\" height=\"4096\" data-original=\"https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/ep_poll-2602x4096.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-516\"  sizes=\"auto, (max-width: 2602px) 100vw, 2602px\" \/><\/div><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">5. \u76d1\u542c\u53e5\u67c4\u6d3b\u8dc3\u89e6\u53d1\u56de\u8c03ep_poll_callback<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u5916\u90e8socket\u6d3b\u8dc3<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/\u7b49\u5f85\u961f\u5217\u6ce8\u518c\u5524\u9192.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"1925\" height=\"1438\" data-original=\"https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/\u7b49\u5f85\u961f\u5217\u6ce8\u518c\u5524\u9192.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-526\"  sizes=\"auto, (max-width: 1925px) 100vw, 1925px\" \/><\/div><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>ep_poll_callback\u51fd\u6570<\/strong><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u4e0b\u6587\u4ee3\u7801\u5df2\u683c\u5f0f\u5316\u5904\u7406\uff0c\u5e76\u9002\u5f53\u7b80\u5316\u53ea\u4fdd\u7559\u6838\u5fc3\u903b\u8f91<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ linux-5.4\/fs\/eventpoll.c\nstatic int ep_poll_callback(wait_queue_entry_t *wait, unsigned mode, int sync, void *key)\n{\n    int pwake = 0;\n    struct epitem *epi = ep_item_from_wait(wait);\n    struct eventpoll *ep = epi-&gt;ep;\n    \/* \u672c\u6b21\u5524\u9192\u643a\u5e26\u7684\u5c31\u7eea\u4e8b\u4ef6\u4f4d,\u4f8b\u5982 POLLIN\u3001POLLOUT\u3001POLLERR\u7b49\uff0c\u4e5f\u5c31\u662f\u5e95\u5c42\u8fd9\u6b21\u8ba4\u4e3a\u53d1\u751f\u4e86\u54ea\u4e9bpoll\u8bed\u4e49\u4e0a\u7684\u4e8b\u4ef6 *\/\n    __poll_t pollflags = key_to_poll(key);\n    unsigned long flags;\n    int ewake = 0;\n\n    read_lock_irqsave(&amp;ep-&gt;lock, flags);\n\n    \/* \u548c\u7528\u6237\u6ce8\u518c\u7684\u5174\u8da3\u505a\u4ea4\u96c6\u8fc7\u6ee4,\u5982\u679c\u6ca1\u6709\u7528\u6237\u611f\u5174\u8da3\u7684\u4e8b\u4ef6\u53d1\u751f,\u5219\u4e0d\u5524\u9192\u7528\u6237\u7a7a\u95f4\u7684\u7ebf\u7a0b *\/\n    if (pollflags &amp;&amp; !(pollflags &amp; epi-&gt;event.events))\n        goto out_unlock;\n\n    \/**\n     * \u5f53\u6b63\u5728\u628a\u5c31\u7eea\u4e8b\u4ef6\u4ece\u5185\u6838\u4ea4\u7ed9\u7528\u6237\u6001\u7684\u90a3\u6bb5\u65f6\u95f4\u91cc\u7684\u90a3\u6bb5\u65f6\u95f4\u91cc\n     * \u65b0\u6765\u7684I\/O\u5c31\u7eea\u4e0d\u80fd\u518d\u53bb\u52a8rdllist,\u53ea\u80fd\u5148\u6302\u5230ovflist\u4e0a\n     *\/\n    if (READ_ONCE(ep-&gt;ovflist) != EP_UNACTIVE_PTR) {\n        if (epi-&gt;next == EP_UNACTIVE_PTR &amp;&amp;\n            chain_epi_lockless(epi))\n            \/* \u5411\u5185\u6838\u7535\u6e90\u7ba1\u7406\u5b50\u7cfb\u7edf\u767b\u8bb0,\u9632\u6b62\u4f11\u7720 *\/\n            ep_pm_stay_awake_rcu(epi);\n        goto out_unlock;\n    }\n\n    if (!ep_is_linked(epi) &amp;&amp;\n        list_add_tail_lockless(&amp;epi-&gt;rdllink, &amp;ep-&gt;rdllist)) {\n        \/* \u5411\u5185\u6838\u7535\u6e90\u7ba1\u7406\u5b50\u7cfb\u7edf\u767b\u8bb0,\u9632\u6b62\u4f11\u7720 *\/\n        ep_pm_stay_awake_rcu(epi);\n    }\n\n    \/* \u5982\u679c\u5904\u4e8e\u6fc0\u6d3b\u72b6\u6001\uff0c\u540c\u65f6\u5524\u9192\u4e8b\u4ef6\u8f6e\u8be2\u7b49\u5f85\u5217\u8868\u548c-&gt;poll()\u65b9\u6cd5\u7684\u7b49\u5f85\u5217\u8868 *\/\n    if (waitqueue_active(&amp;ep-&gt;wq)) {\n        wake_up(&amp;ep-&gt;wq);\n    }\n    if (waitqueue_active(&amp;ep-&gt;poll_wait))\n        pwake++;\n\nout_unlock:\n    read_unlock_irqrestore(&amp;ep-&gt;lock, flags);\n\n    if (pwake)\n        ep_poll_safewake(&amp;ep-&gt;poll_wait);\n\n    if (!(epi-&gt;event.events &amp; EPOLLEXCLUSIVE))\n        ewake = 1;\n\n    if (pollflags &amp; POLLFREE) {\n        list_del_init(&amp;wait-&gt;entry);\n        smp_store_release(&amp;ep_pwq_from_wait(wait)-&gt;whead, NULL);\n    }\n\n    return ewake;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6838\u5fc3\u601d\u60f3<\/strong><br>\u6839\u636e<code>ovflist<\/code>\u7684\u72b6\u6001,\u5c06\u65b0\u6d3b\u8dc3\u7684\u4e8b\u4ef6\u6dfb\u52a0\u5230\u5c31\u7eea\u961f\u5217\u6216\u8005\u7f13\u5b58\u961f\u5217\u4e2d<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/ep_poll_callback-scaled.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"1560\" data-original=\"https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/ep_poll_callback-scaled.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-517\"  sizes=\"auto, (max-width: 2560px) 100vw, 2560px\" \/><\/div><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">6. \u626b\u63cf\u5c31\u7eea\u94fe\u8868<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>ep_send_events\u51fd\u6570<\/strong><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u9664\u6ce8\u91ca\u5916\uff0c\u6240\u6709\u4ee3\u7801\u5747\u672a\u5220\u6539<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ linux-5.4\/fs\/eventpoll.c\nstatic int ep_send_events(struct eventpoll *ep,\n              struct epoll_event __user *events, int maxevents)\n{\n    struct ep_send_events_data esed;\n\n    esed.maxevents = maxevents;\n    esed.events = events;\n\n    \/* \u626b\u63cf\u5c31\u7eea\u961f\u5217 *\/\n    ep_scan_ready_list(ep, ep_send_events_proc, &amp;esed, 0, false);\n    return esed.res;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>ep_scan_ready_list\u51fd\u6570<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>ep_scan_ready_list<\/code>\u51fd\u6570\u5728<code>epoll<\/code>\u6d41\u7a0b\u4e2d\u529f\u80fd\u53ca\u91cd\u8981\u4e14\u590d\u6742\uff0c\u8fd9\u91cc\u4fdd\u7559\u5b8c\u6574\u6ce8\u91ca\u548c\u6e90\u7801\uff0c\u65b9\u4fbf\u8bfb\u8005\u9605\u8bfb\u7406\u89e3<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u9664\u6ce8\u91ca\u5916\uff0c\u6240\u6709\u4ee3\u7801\u5747\u672a\u5220\u6539<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ linux-5.4\/fs\/eventpoll.c\n\/**\n * ep_scan_ready_list - Scans the ready list in a way that makes possible for\n *                      the scan code, to call f_op-&gt;poll(). Also allows for\n *                      O(NumReady) performance.\n *\n * @ep: Pointer to the epoll private data structure.\n * @sproc: Pointer to the scan callback.\n * @priv: Private opaque data passed to the @sproc callback.\n * @depth: The current depth of recursive f_op-&gt;poll calls.\n * @ep_locked: caller already holds ep-&gt;mtx\n *\n * Returns: The same integer error code returned by the @sproc callback.\n *\n * ep_scan_ready_list - \u4ee5\u4e00\u79cd\u80fd\u591f\u4f7f\u626b\u63cf\u4ee3\u7801\u8c03\u7528 f_op-&gt;poll() \u7684\u65b9\u5f0f\u626b\u63cf\u5c31\u7eea\u5217\u8868\u3002\u540c\u65f6\u8fd8\u80fd\u5b9e\u73b0 O(NumReady) \u7684\u6027\u80fd\n * @ep\uff1a\u6307\u5411 epoll \u79c1\u6709\u6570\u636e\u7ed3\u6784\u7684\u6307\u9488\n * @sproc\uff1a\u6307\u5411\u626b\u63cf\u56de\u8c03\u51fd\u6570\u7684\u6307\u9488\n * @priv\uff1a\u4f20\u9012\u7ed9 @sproc \u56de\u8c03\u51fd\u6570\u7684\u79c1\u6709\u4e0d\u900f\u660e\u6570\u636e\n * @depth\uff1a\u9012\u5f52\u8c03\u7528 f_op-&gt;poll \u7684\u5f53\u524d\u6df1\u5ea6\n * @ep_locked\uff1a\u8c03\u7528\u8005\u662f\u5426\u5df2\u7ecf\u6301\u6709ep-&gt;mtx\u9501\n *\n * \u8fd4\u56de\u503c\uff1a\u4e0e @sproc \u56de\u8c03\u6240\u8fd4\u56de\u7684\u76f8\u540c\u6574\u6570\u9519\u8bef\u4ee3\u7801\n *\/\nstatic __poll_t ep_scan_ready_list(struct eventpoll *ep,\n                  __poll_t (*sproc)(struct eventpoll *,\n                       struct list_head *, void *),\n                  void *priv, int depth, bool ep_locked)\n{\n    __poll_t res;\n    int pwake = 0;\n    struct epitem *epi, *nepi;\n    LIST_HEAD(txlist);\n\n    lockdep_assert_irqs_enabled();\n\n    \/**\n     * We need to lock this because we could be hit by\n     * eventpoll_release_file() and epoll_ctl().\n     * \n     * \u8fd9\u91cc\u9700\u8981\u9501\u5b9a\u8fd9\u4e2a\uff0c\u56e0\u4e3a\u53ef\u80fd\u4f1a\u53d7\u5230\n     * eventpoll_release_file()\u548cepoll_ctl()\u7684\u5f71\u54cd\n     *\/\n    if (!ep_locked)\n        mutex_lock_nested(&amp;ep-&gt;mtx, depth);\n\n    \/**\n     * Steal the ready list, and re-init the original one to the\n     * empty list. Also, set ep-&gt;ovflist to NULL so that events\n     * happening while looping w\/out locks, are not lost. We cannot\n     * have the poll callback to queue directly on ep-&gt;rdllist,\n     * because we want the \"sproc\" callback to be able to do it\n     * in a lockless way.\n     * \n     * \u7a83\u53d6\u5c31\u7eea\u5217\u8868\uff0c\u5e76\u5c06\u539f\u59cb\u5217\u8868\u91cd\u65b0\u521d\u59cb\u5316\u4e3a\u7a7a\u5217\u8868\n     * \u540c\u65f6\uff0c\u5c06ep-&gt;ovflist\u8bbe\u7f6e\u4e3aNULL\uff0c\u8fd9\u6837\u5728\u65e0\u9501\u5faa\u73af\u671f\u95f4\u53d1\u751f\u7684\u4e8b\u4ef6\u5c31\u4e0d\u4f1a\u4e22\u5931\n     * \u4e0d\u80fd\u8ba9\u8f6e\u8be2(poll)\u56de\u8c03\u76f4\u63a5\u6392\u961f\u5230ep-&gt;rdllist\u4e0a\uff0c\u56e0\u4e3a\u6211\u4eec\u5e0c\u671b\u7279\u6b8a\u5904\u7406(sproc)\u56de\u8c03\u80fd\u591f\u4ee5\u65e0\u9501\u7684\u65b9\u5f0f\u6267\u884c\u6b64\u64cd\u4f5c\n     *\/\n    write_lock_irq(&amp;ep-&gt;lock);\n    \/* \u5c06\u5c31\u7eea\u5217\u8868\u590d\u5236\u5230\u4e34\u65f6\u5217\u8868 *\/\n    list_splice_init(&amp;ep-&gt;rdllist, &amp;txlist);\n    \/* \u5c06\u7f13\u51b2\u94fe\u8868ep-&gt;ovflist\u8bbe\u7f6e\u4e3aNULL *\/\n    WRITE_ONCE(ep-&gt;ovflist, NULL);\n    write_unlock_irq(&amp;ep-&gt;lock);\n\n    \/**\n     * Now call the callback function.\n     *\n     * \u5728\u6ca1\u6709\u9501\u7684\u60c5\u51b5\u4e0b\u8c03\u7528\u56de\u8c03\u51fd\u6570\n     *\/\n    res = (*sproc)(ep, &amp;txlist, priv);\n\n    write_lock_irq(&amp;ep-&gt;lock);\n    \/*\n     * During the time we spent inside the \"sproc\" callback, some\n     * other events might have been queued by the poll callback.\n     * We re-insert them inside the main ready-list here.\n     * \n     * \u5728\u6211\u4eec\u5904\u4e8e\"sproc\"\u56de\u8c03\u51fd\u6570\u5185\u90e8\u7684\u8fd9\u6bb5\u65f6\u95f4\u91cc\n     * \u8fd8\u6709\u4e00\u4e9b\u5176\u4ed6\u4e8b\u4ef6\u53ef\u80fd\u5df2\u88ab\u8f6e\u8be2\u56de\u8c03\u51fd\u6570\u52a0\u5165\u5230\u4e86\u961f\u5217\u4e2d\n     * \u6211\u4eec\u5728\u6b64\u5904\u5c06\u5b83\u4eec\u91cd\u65b0\u63d2\u5165\u5230\u4e3b\u5c31\u7eea\u5217\u8868\u4e2d\n     *\/\n    for (nepi = READ_ONCE(ep-&gt;ovflist); (epi = nepi) != NULL;\n         nepi = epi-&gt;next, epi-&gt;next = EP_UNACTIVE_PTR) {\n        \/*\n         * We need to check if the item is already in the list.\n         * During the \"sproc\" callback execution time, items are\n         * queued into -&gt;ovflist but the \"txlist\" might already\n         * contain them, and the list_splice() below takes care of them.\n         * \n         * \u6211\u4eec\u9700\u8981\u68c0\u67e5\u4e00\u4e0b\u8fd9\u4e2a\u6761\u76ee\u662f\u5426\u5df2\u7ecf\u5728\u5217\u8868\u91cc\u4e86\n         * \u5728\"\u7279\u6b8a\u5904\u7406(sproc)\"\u56de\u8c03\u6267\u884c\u671f\u95f4\u6761\u76ee\u4f1a\u88ab\u6392\u5165-&gt;ovflist\n         * \u4f46txlist\u91cc\u53ef\u80fd\u5df2\u7ecf\u5305\u542b\u5b83\u4eec\u4e86,\u800c\u4e0b\u9762\u7684list_splice()\u64cd\u4f5c\u4f1a\u8d1f\u8d23\u5904\u7406\u8fd9\u4e9b(\u5df2\u5b58\u5728\u7684)\u6761\u76ee\n         *\/\n        if (!ep_is_linked(epi)) {\n            \/*\n             * -&gt;ovflist is LIFO, so we have to reverse it in order\n             * to keep in FIFO.\n             * \n             * -&gt; \u7531\u4e8e\u961f\u5217\u9075\u5faa\u540e\u8fdb\u5148\u51fa\u539f\u5219\uff0c\u6240\u4ee5\u6211\u4eec\u9700\u8981\u5bf9\u5176\u8fdb\u884c\u53cd\u8f6c\uff0c\u4ee5\u4fbf\u4fdd\u6301\u5148\u8fdb\u5148\u51fa\u7684\u987a\u5e8f\u3002\n             *\/\n            list_add(&amp;epi-&gt;rdllink, &amp;ep-&gt;rdllist);\n            ep_pm_stay_awake(epi);\n        }\n    }\n    \/*\n     * We need to set back ep-&gt;ovflist to EP_UNACTIVE_PTR, so that after\n     * releasing the lock, events will be queued in the normal way inside\n     * ep-&gt;rdllist.\n     * \n     * \u6211\u4eec\u9700\u8981\u5c06 ep-&gt;ovflist \u8bbe\u4e3a EP_UNACTIVE_PTR\uff0c\u8fd9\u6837\u5728\u91ca\u653e\u9501\u4e4b\u540e\uff0c\u4e8b\u4ef6\u5c31\u4f1a\u6309\u7167\u6b63\u5e38\u65b9\u5f0f\u4f9d\u6b21\u5b58\u653e\u5728 ep-&gt;rdllist \u4e2d\u3002\n     *\/\n    WRITE_ONCE(ep-&gt;ovflist, EP_UNACTIVE_PTR);\n\n    \/*\n     * Quickly re-inject items left on \"txlist\".\n     *\/\n    list_splice(&amp;txlist, &amp;ep-&gt;rdllist);\n    __pm_relax(ep-&gt;ws);\n\n    if (!list_empty(&amp;ep-&gt;rdllist)) {\n        \/*\n         * Wake up (if active) both the eventpoll wait list and\n         * the -&gt;poll() wait list (delayed after we release the lock).\n         * \n         * (\u5982\u679c\u5904\u4e8e\u6fc0\u6d3b\u72b6\u6001)\u540c\u65f6\u5524\u9192\u4e8b\u4ef6\u8f6e\u8be2\u7b49\u5f85\u5217\u8868\u548c\n         * -&gt;poll()\u7b49\u5f85\u5217\u8868(\u5728\u6211\u4eec\u91ca\u653e\u9501\u4e4b\u540e\u5ef6\u8fdf\u8fdb\u884c)\n         *\/\n        if (waitqueue_active(&amp;ep-&gt;wq))\n            wake_up(&amp;ep-&gt;wq);\n        if (waitqueue_active(&amp;ep-&gt;poll_wait))\n            pwake++;\n    }\n    write_unlock_irq(&amp;ep-&gt;lock);\n\n    if (!ep_locked)\n        mutex_unlock(&amp;ep-&gt;mtx);\n\n    \/**\n     * We have to call this outside the lock\n     * \u6211\u4eec\u5f97\u628a\u8fd9\u4e2a\u4e1c\u897f\u4ece\u9501\u91cc\u53d6\u51fa\u6765\u3002\n     *\/\n    if (pwake)\n        ep_poll_safewake(&amp;ep-&gt;poll_wait);\n\n    return res;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6838\u5fc3\u601d\u60f3<\/strong><br><code>ep_scan_ready_list<\/code>\u51fd\u6570\u7684\u6267\u884c\u53ef\u4ee5\u5206\u4e3a\u4ee5\u4e0b\u6b65\u9aa4<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u590d\u5236\u5c31\u7eea\u94fe\u8868\u7136\u540e\u5c06\u526f\u672c\u4f20\u5165\u51fd\u6570\u6307\u9488<code>sproc<\/code>\uff0c\u8fd9\u91cc\u4f1a\u6839\u636e\u4e0d\u540c\u7684\u573a\u666f\u4f7f\u7528<code>ep_read_events_proc<\/code>\u6216<code>ep_send_events_proc<\/code>\u6765\u5bf9\u5c31\u7eea\u94fe\u8868\u5904\u7406<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>ep_read_events_proc\u51fd\u6570\uff1a<\/strong>\u7528\u4e8e\u5904\u7406\u5c31\u7eea\u94fe\u8868\uff0c\u8fd4\u56de\u5c31\u7eea\u4e8b\u4ef6\u7ed9\u7528\u6237\u6001\uff0c\u5904\u7406\u8fb9\u6cbf\u89e6\u53d1\u548c\u6c34\u5e73\u89e6\u53d1\u4e8b\u4ef6<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>ep_send_events_proc\u51fd\u6570\uff1a<\/strong><code>epoll<\/code>\u6a21\u5757\u9762\u5411<code>VFS<\/code>\u7684<code>poll<\/code>\u65b9\u6cd5<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u5173\u4e8e\u5bf9rdllist\u5c31\u7eea\u961f\u5217\u7684\u5904\u7406\uff1a<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u961f\u5217\uff0c\u5c31\u7eea\u961f\u5217\u7684\u503c\u8f6c\u79fb\u5230\u4e34\u65f6\u961f\u5217\u4e2d\u3002\u4ea4\u7ed9<code>ep_read_events_proc<\/code>\u6216\u8005<code>ep_send_events_proc<\/code>\u53bb\u5904\u7406\uff0c\u7136\u540e\u628a\u5728\u8fd9\u671f\u95f4\u6dfb\u52a0\u5230\u6ea2\u51fa\u7f13\u5b58\u961f\u5217\u4e2d\u7684\u8282\u70b9\uff0c\u91cd\u65b0\u653e\u56de\u5c31\u7eea\u961f\u5217\u4e2d\u3002\u6700\u540e\u5c06\u5904\u7406\u5b8c\u540e\u5c06\u6ca1\u6709\u901a\u77e5\u7684\u8282\u70b9\u91cd\u65b0\u653e\u56de\u5c31\u7eea\u961f\u5217\u4e2d<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/ep_scan_ready_list-scaled.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"2444\" data-original=\"https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/ep_scan_ready_list-scaled.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-533\"  sizes=\"auto, (max-width: 2560px) 100vw, 2560px\" \/><\/div><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u591a\u5c42\u5d4c\u5957\u4e0e\u9501\uff1a<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u8fd9\u91cc\u9700\u8981\u6ce8\u610f<code>ep_read_events_proc<\/code>\u51fd\u6570\u548c<code>ep_send_events_proc<\/code>\u51fd\u6570\uff0c\u90fd\u4f1a\u5728\u5185\u90e8\u8c03\u7528<code>ep_item_poll<\/code>\u51fd\u6570\u6765\u5bf9\u7ea2\u9ed1\u6811\u8282\u70b9\u6267\u884c\u7b49\u4ef7\u4e8e<code>vfs<\/code>\u7684<code>poll<\/code>\u7684\u64cd\u4f5c\uff0c\u5982\u679c\u8fd9\u65f6\u9047\u5230\u4e86\u5d4c\u5957<code>epoll<\/code>\u7684\u60c5\u51b5\uff0c\u53ca\u68c0\u67e5\u7684\u8282\u70b9\u662f<code>epoll<\/code>\u8282\u70b9\uff0c\u90a3\u4e48\u8fd9\u65f6\u4f1a\u518d\u8c03\u7528<code>ep_send_events_proc<\/code>\u51fd\u6570\uff0c\u9020\u6210\u4e00\u4e2a\u5d4c\u5957\u8c03\u7528\uff0c\u8fd9\u79cd\u5d4c\u5957\u7684\u51fa\u53e3\u662f\u627e\u5230\u6700\u7ec8\u7684\u4e0d\u662f<code>epoll<\/code>\u7684\u53e5\u67c4<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u7531\u4e8eep_insert\u51fd\u6570\u63d2\u5165\u65f6\u5c31\u68c0\u67e5\u8fc7\u73af\u8def\u95ee\u9898\uff0c\u6240\u4ee5\u8fd9\u91cc\u4e0d\u4f1a\u51fa\u73b0\u73af\u5f62\u8c03\u7528<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/ep_scan_ready_list\u9012\u5f52.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"1609\" height=\"1266\" data-original=\"https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/ep_scan_ready_list\u9012\u5f52.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-519\"  sizes=\"auto, (max-width: 1609px) 100vw, 1609px\" \/><\/div><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">7. \u5206\u7c7b\u5904\u7406\u6c34\u5e73\u89e6\u53d1(LT)\u548c\u8fb9\u6cbf\u89e6\u53d1(ET)\u5e76\u8fd4\u56de\u5c31\u7eea\u4e8b\u4ef6<\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u4e0b\u6587\u4ee3\u7801\u5df2\u683c\u5f0f\u5316\u5904\u7406\uff0c\u5e76\u9002\u5f53\u7b80\u5316\u53ea\u4fdd\u7559\u6838\u5fc3\u903b\u8f91<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ linux-5.4\/fs\/eventpoll.c\nstatic __poll_t ep_send_events_proc(struct eventpoll *ep, struct list_head *head,\n                   void *priv)\n{\n    struct ep_send_events_data *esed = priv;\n    __poll_t revents;\n    struct epitem *epi, *tmp;\n    struct epoll_event __user *uevent = esed-&gt;events;\n    struct wakeup_source *ws;\n    poll_table pt;\n\n    init_poll_funcptr(&amp;pt, NULL);\n    esed-&gt;res = 0;\n\n    \/* \u904d\u5386\u4e34\u65f6\u961f\u5217\u5373\u5c31\u7eea\u961f\u5217\u7684\u526f\u672c *\/ \n    list_for_each_entry_safe(epi, tmp, head, rdllink) {\n        \/* \u4ece\u5f53\u524d\u94fe\u8868\u91cc\u6458\u6389\u8282\u70b9 *\/\n        list_del_init(&amp;epi-&gt;rdllink);\n\n        \/* \u68c0\u67e5\u4e8b\u4ef6\u662f\u5426\u5c31\u7eea *\/\n        revents = ep_item_poll(epi, &amp;pt, 1);\n        if (!revents)\n            continue;\n\n        \/* \u5c06\u5c31\u7eea\u4e8b\u4ef6\u548c\u5bf9\u5e94\u7684\u8282\u70b9\u8fd4\u56de\u5230\u7528\u6237\u6001 *\/\n        if (__put_user(revents, &amp;uevent-&gt;events) ||\n            __put_user(epi-&gt;event.data, &amp;uevent-&gt;data)) {\n            \/* \u5982\u679c\u590d\u5236\u5230\u7528\u6237\u6001\u5931\u8d25\uff0c\u5c06\u8282\u70b9\u91cd\u65b0\u52a0\u5165\u5c31\u7eea\u961f\u5217 *\/\n            list_add(&amp;epi-&gt;rdllink, head);\n            ep_pm_stay_awake(epi);\n            if (!esed-&gt;res)\n                esed-&gt;res = -EFAULT;\n            return 0;\n        }\n        esed-&gt;res++;\n        uevent++;\n        \/* Edge Triggered,\u8fb9\u7f18\u89e6\u53d1\u6a21\u5f0f\u4e0b,\u4e8b\u4ef6\u53ea\u5904\u7406\u4e00\u6b21\u4e0d\u5411\u7528\u6237\u91cd\u590d\u4e0a\u62a5\u540c\u4e00\u76d1\u542c *\/\n        if (epi-&gt;event.events &amp; EPOLLONESHOT)\n            \/**\n             * \u53bb\u6389EPOLLIN\u3001EPOLLOUT\u7b49\u771f\u6b63\u7684I\/O\u4e8b\u4ef6\u63a9\u7801,\u53ea\u4fdd\u7559\u79c1\u6709\/\u6a21\u5f0f\u4f4d(WAKEUP\u3001ONESHOT\u3001ET\u3001EXCLUSIVE)\n             * \u4e4b\u540e\u5728ep_poll_callback()\u91cc\u4f1a\u5148\u68c0\u67e5:\u63a9\u7801\u91cc\u53ea\u5269\u79c1\u6709\u4f4d\u2192\u89c6\u4e3adisabled(\u5df2\u7981\u7528),\u5373\u4f7f\u5e95\u5c42fd\u518d\u6b21\u53ef\u8bfb\n             * \u4e5f\u4e0d\u4f1a\u518d\u8fdbrdllist,\u76f4\u5230\u7528\u6237epoll_ctl(EPOLL_CTL_MOD,...)\u91cd\u65b0\u5199\u4e0aEPOLLIN\u7b49\n               *\/\n            epi-&gt;event.events &amp;= EP_PRIVATE_BITS;\n        \/* Level Triggered,\u6c34\u5e73\u89e6\u53d1\u6a21\u5f0f\u4e0b,\u6761\u4ef6\u8fd8\u5728\u5c31\u7ee7\u7eed\u62a5,\u4e8b\u4ef6\u4e0a\u62a5\u540e\u91cd\u65b0\u52a0\u5165\u5c31\u7eea\u961f\u5217 *\/\n        else if (!(epi-&gt;event.events &amp; EPOLLET)) {\n            list_add_tail(&amp;epi-&gt;rdllink, &amp;ep-&gt;rdllist);\n            ep_pm_stay_awake(epi);\n        }\n    }\n\n    return 0;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>LT\u6a21\u5f0f\u548cET\u6a21\u5f0f<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">\u6a21\u5f0f<\/th><th class=\"has-text-align-left\" data-align=\"left\">\u6807\u5fd7<\/th><th class=\"has-text-align-left\" data-align=\"left\">\u542b\u4e49<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>LT<\/code>\uff08<code>Level Trigger<\/code>\uff0c\u6c34\u5e73\u89e6\u53d1\uff09<\/td><td class=\"has-text-align-left\" data-align=\"left\">\u9ed8\u8ba4\uff0c\u4e0d\u8bbe <code>EPOLLET<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">\u53ea\u8981\u6761\u4ef6\u4ecd\u7136\u6210\u7acb\uff08\u4f8b\u5982\u4ecd\u6709\u6570\u636e\u53ef\u8bfb\uff09\uff0c<code>epoll_wait<\/code> \u53ef\u4ee5\u53cd\u590d\u901a\u77e5\u4f60<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>ET<\/code>\uff08<code>Edge Trigger<\/code>\uff0c\u8fb9\u6cbf\u89e6\u53d1\uff09<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>EPOLLET<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">\u53ea\u5728\u6761\u4ef6\u4ece\u65e0\u5230\u6709\uff08\u6216\u53d1\u751f\u53d8\u5316\uff09\u65f6\u901a\u77e5\u4e00\u6b21\uff1b\u4ea4\u4ed8\u540e\u82e5\u6761\u4ef6\u8fd8\u5728\uff0c\u4e0d\u4f1a\u56e0 <code>LT<\/code> \u90a3\u6837\u81ea\u52a8\u518d\u8fdb\u5c31\u7eea\u961f\u5217<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u5904\u7406\u4e34\u65f6\u961f\u5217\u4e2d\u7684\u6bcf\u4e00\u8282\u70b9\uff0c\u68c0\u67e5\u662f\u5426\u6709\u6d3b\u8dc3\u4e8b\u4ef6<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6838\u5fc3\u601d\u60f3\uff1a<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u5982\u679c\u6709\u5219\u5c06\u4e8b\u4ef6\u8fd4\u56de\u7ed9\u7528\u6237\u6001\uff0c\u7136\u540e\u6309\u7167<code>LT<\/code>\u6a21\u5f0f\u548c<code>ET<\/code>\u6a21\u5f0f\u5206\u522b\u5904\u7406<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u5bf9\u4e8e<code>LT<\/code>\u6a21\u5f0f\uff0c\u4f1a\u5c06\u89e6\u53d1\u7684\u4e8b\u4ef6\u91cd\u65b0\u653e\u56de\u5c31\u7eea\u961f\u5217\u4e2d\uff0c\u5728\u4e0b\u4e00\u6b21\u4f1a\u7ee7\u7eed\u8fd4\u56de\u7ed9\u7528\u6237\u6001\u3002\u5bf9\u4e8e<code>ET<\/code>\u6a21\u5f0f\u5f53\u524d\u4e8b\u4ef6\u5904\u7406\u5b8c\u540e\u5c31\u4e0d\u518d\u5904\u7406<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/ep_send_events_proc.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"2553\" height=\"2187\" data-original=\"https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/ep_send_events_proc.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-536\"  sizes=\"auto, (max-width: 2553px) 100vw, 2553px\" \/><\/div><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">\u4e03\u3001epoll\u5b9e\u4f8b\u589e\u5220\u6539\u67e5<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1. ep_insert\u51fd\u6570<\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u4e0b\u6587\u4ee3\u7801\u5df2\u683c\u5f0f\u5316\u5904\u7406\uff0c\u5e76\u9002\u5f53\u7b80\u5316\u53ea\u4fdd\u7559\u6838\u5fc3\u903b\u8f91<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ linux-5.4\/fs\/eventpoll.c\n\/**\n * \u8bbe\u7f6e\u7b49\u5f85\u961f\u5217\u56de\u8c03\u51fd\u6570\u662fep_poll_callback\uff0c\u5e76\u5c06\u5bf9\u5e94\u7684\u7b49\u5f85\u961f\u5217\u548c\u5bf9\u5e94\u7684epitem\u8282\u70b9\u8bb0\u5f55\n * \u5728\u65b0\u521b\u5efa\u7684eppoll_entry\u8282\u70b9\u4e2d\uff0c\u5176\u52a0\u5165\u5230\u5bf9\u5e94\u7684epitem\u8282\u70b9\u7684\u7b49\u5f85\u961f\u5217\u94fe\u8868\u4e2d\n *\/\nstatic void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead,\n                 poll_table *pt)\n{\n    struct epitem *epi = ep_item_from_epqueue(pt);\n    struct eppoll_entry *pwq;\n\n    if (epi-&gt;nwait &gt;= 0 &amp;&amp; (pwq = kmem_cache_alloc(pwq_cache, GFP_KERNEL))) {\n        \/* \u8bbe\u7f6e\u7b49\u5f85\u961f\u5217\u56de\u8c03\u4e3a ep_poll_callback,\u5e76\u8bb0\u5f55\u5bf9\u5e94\u7684\u7b49\u5f85\u961f\u5217\u548c\u5bf9\u5e94\u7684epitem\u8282\u70b9 *\/\n        init_waitqueue_func_entry(&amp;pwq-&gt;wait, ep_poll_callback);\n        pwq-&gt;whead = whead;\n        pwq-&gt;base = epi;\n        if (epi-&gt;event.events &amp; EPOLLEXCLUSIVE)\n            add_wait_queue_exclusive(whead, &amp;pwq-&gt;wait);\n        else\n            add_wait_queue(whead, &amp;pwq-&gt;wait);\n        \/* \u628a\u8fd9\u4e2apwq\u6dfb\u52a0\u5230\u5230\u8be5epitem\u7684\u94fe\u8868\u4e0a *\/\n        list_add_tail(&amp;pwq-&gt;llink, &amp;epi-&gt;pwqlist);\n        epi-&gt;nwait++;\n    } else {\n        epi-&gt;nwait = -1;\n    }\n}\n\n\/\/ linux-5.4\/fs\/eventpoll.c\nstatic int ep_insert(struct eventpoll *ep, const struct epoll_event *event,\n             struct file *tfile, int fd, int full_check)\n{\n    int pwake = 0;\n    __poll_t revents;\n    struct epitem *epi;\n    struct ep_pqueue epq;\n\n    \/* \u521d\u59cb\u5316\u5404\u7c7b\u94fe\u8868\uff0c\u8282\u70b9*\/\n    INIT_LIST_HEAD(&amp;epi-&gt;rdllink);\n    INIT_LIST_HEAD(&amp;epi-&gt;fllink);\n    INIT_LIST_HEAD(&amp;epi-&gt;pwqlist);\n    epi-&gt;ep = ep;\n    ep_set_ffd(&amp;epi-&gt;ffd, tfile, fd);\n    epi-&gt;event = *event;\n    epi-&gt;nwait = 0;\n    epi-&gt;next = EP_UNACTIVE_PTR;\n\n    \/* \u521b\u5efa\u7535\u6e90\u7ba1\u7406\u76f8\u5173\u7684\u5524\u9192\u6e90 *\/\n    ep_create_wakeup_source(epi);\n\n    \/**\n     * \u521b\u5efa\u5185\u6838vfs_poll\u4f7f\u7528\u7684poll_table,\u5e76\u5c06poll_table-&gt;_qproc\u8bbe\u7f6e\u4e3aep_ptable_queue_proc\n     * \u5728\u540e\u7eedep_item_poll()\u4e2d\u8c03\u7528\u5177\u4f53\u5185\u6838\u5bf9\u8c61\u7684poll\u65b9\u6cd5\u65f6\u4f7f\u7528\n     *\/\n    epq.epi = epi;\n    init_poll_funcptr(&amp;epq.pt, ep_ptable_queue_proc);\n\n    \/**\n     * \u628a\u65b0epitem\u63a5\u5230\u76ee\u6807\u6587\u4ef6\u7684poll\/waitqueue\u961f\u5217\u4e0a\uff0c\u5e76\u987a\u4fbf\u8bfb\u51fa\u6b64\u523b\u662f\u5426\u5df2\u7ecf\u5c31\u7eea\u7684\u4e8b\u4ef6\u4f4d\n     * \u9700\u8981\u6ce8\u610f\u5728\u6b64\u64cd\u4f5c\u5b8c\u6210\u540e\u6ce8\u518c\u7684\u56de\u8c03\u51fd\u6570\u5c31\u53ef\u4ee5\u5f00\u59cb\u5904\u7406\u65b0\u7684\u9879\u4e86\n     *\/\n    revents = ep_item_poll(epi, &amp;epq.pt, 1);\n\n    \/**\n     * epitem\u901a\u8fc7epi-&gt;fllink\u6302\u5230\u88ab\u76d1\u63a7\u6587\u4ef6 tfile-&gt;f_ep_link\u5373epi-&gt;ffd.file\u4e0a\u5f53\u8fd9\u4e2astruct file\u88ab\u5173\u95ed\u65f6\n     * \u5185\u6838\u80fd\u987a\u7740f_ep_links\u627e\u5230\u6240\u6709\u8fd8\u5728\u76d1\u542c\u5b83\u7684epoll\u9879\uff0c\u628a\u5b83\u4eec\u5378\u6389\n     *\/\n    list_add_tail_rcu(&amp;epi-&gt;fllink, &amp;tfile-&gt;f_ep_links);\n\n    \/* \u5c06\u8282\u70b9\u63d2\u5165\u7ea2\u9ed1\u6811\u4e2d *\/\n    ep_rbtree_insert(ep, epi);\n\n    \/**\n     * We have to drop the new item inside our item list to keep track of it\n     * \u6211\u4eec\u5f97\u4ece\u6211\u4eec\u7684\u7269\u54c1\u6e05\u5355\u4e2d\u5220\u9664\u8fd9\u4e2a\u65b0\u9879\u76ee\uff0c\u4ee5\u4fbf\u5bf9\u5176\u8fdb\u884c\u8ddf\u8e2a\u7ba1\u7406\n     *\/\n    write_lock_irq(&amp;ep-&gt;lock);\n\n    \/* \u5982\u679c\u8be5\u6587\u4ef6\u5df2\u7ecf\u201c\u51c6\u5907\u5c31\u7eea\u201d\uff0c\u6211\u4eec\u5c31\u5c06\u5176\u653e\u5165\u201c\u5df2\u51c6\u5907\u5c31\u7eea\u201d\u7684\u5217\u8868\u4e2d *\/\n    if (revents &amp;&amp; !ep_is_linked(epi)) {\n        list_add_tail(&amp;epi-&gt;rdllink, &amp;ep-&gt;rdllist);\n        ep_pm_stay_awake(epi);\n\n        \/* \u901a\u77e5\u7b49\u5f85\u4e2d\u7684\u4efb\u52a1\uff0c\u4e8b\u4ef6\u5df2\u51c6\u5907\u597d\u53ef\u4f9b\u4f7f\u7528 *\/\n        if (waitqueue_active(&amp;ep-&gt;wq))\n            wake_up(&amp;ep-&gt;wq);\n        if (waitqueue_active(&amp;ep-&gt;poll_wait))\n            pwake++;\n    }\n\n    write_unlock_irq(&amp;ep-&gt;lock);\n\n    \/* ep-&gt;user\u6240\u6307\u5411\u7684struct user_struct\u91cc\u7684epoll_watches\u8ba1\u6570(\u5f53\u524d\u88abepoll\u76d1\u89c6\u7684\u6761\u76ee\u6570\u91cf)\u52a01 *\/\n    atomic_long_inc(&amp;ep-&gt;user-&gt;epoll_watches);\n\n    \/**\n     * We have to call this outside the lock\n     * \u6211\u4eec\u5f97\u628a\u8fd9\u4e2a\u4e1c\u897f\u4ece\u9501\u91cc\u53d6\u51fa\u6765\n     *\/\n    if (pwake)\n        ep_poll_safewake(&amp;ep-&gt;poll_wait);\n\n    return 0;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6838\u5fc3\u601d\u60f3<\/strong><br>\u51fd\u6570\u5927\u81f4\u5206\u4e3a\u8fd9\u51e0\u90e8\u5206<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u521b\u5efa\u548c\u521d\u59cb\u5316<code>epitem<\/code>\u8282\u70b9\uff0c\u5c06<code>poll_table-&gt;_qproc<\/code>\u8bbe\u7f6e\u4e3a<code>ep_ptable_queue_proc<\/code><\/li>\n\n\n\n<li>\u628a\u65b0<code>epitem<\/code>\u8282\u70b9\u6dfb\u52a0\u5230\u7ea2\u9ed1\u6811\u4e2d\uff0c\u628a\u65b0<code>epitem<\/code>\u63a5\u5230\u76ee\u6807\u6587\u4ef6\u7684<code>poll\/waitqueue<\/code>\u961f\u5217\u4e0a\uff0c\u8fd9\u4e00\u6b65\u4e4b\u540e\u65b0\u4e8b\u4ef6\u5c31\u5f00\u59cb\u68c0\u6d4b\u65b0\u4e8b\u4ef6\u4e86<\/li>\n\n\n\n<li>\u628a<code>epi<\/code>\u8282\u70b9\u6dfb\u52a0\u5230\u5185\u6838<code>f_ep_links<\/code>\u8868\u4e2d\uff0c\u65b9\u4fbf\u5185\u6838\u7ba1\u7406\uff0c\u907f\u514d\u51fa\u73b0\u60ac\u5782\u6307\u9488<\/li>\n\n\n\n<li>\u68c0\u6d4b\u6709\u6ca1\u6709\u65b0\u7684\u4e8b\u4ef6\uff0c\u5982\u679c\u6709\u5219\u5524\u9192\u5c31\u7eea\u961f\u5217<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image size-full\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/ep_insert\u4e3b\u6d41\u7a0b-scaled.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"2119\" height=\"2560\" data-original=\"https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/ep_insert\u4e3b\u6d41\u7a0b-scaled.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-514\"  sizes=\"auto, (max-width: 2119px) 100vw, 2119px\" \/><\/div><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>epoll\u5d4c\u5957<\/strong><br><code>epoll<\/code>\u5728\u6dfb\u52a0\u65b0\u7684\u8282\u70b9\u65f6\uff0c\u662f\u53ef\u4ee5\u5b58\u5728<code>epoll<\/code>\u76d1\u542c<code>epoll<\/code>\u7684\u60c5\u51b5\uff0c\u4f46\u662f<strong>\u4e0d\u5141\u8bb8\u51fa\u73b0\u73af\u5f62\u8c03\u7528\u548c\u8fc7\u6df1\u7684\u5d4c\u5957<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/ep_insert\u5d4c\u5957.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"2212\" height=\"1166\" data-original=\"https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/ep_insert\u5d4c\u5957.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-513\"  sizes=\"auto, (max-width: 2212px) 100vw, 2212px\" \/><\/div><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>ep_rbtree_insert\u51fd\u6570<\/strong><br>\u63d2\u5165\u65b0\u7684\u8282\u70b9<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6e90\u4ee3\u7801\u5982\u4e0b<\/strong><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u9664\u6ce8\u91ca\u5916\uff0c\u6240\u6709\u4ee3\u7801\u5747\u672a\u5220\u6539<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ linux-5.4\/fs\/eventpoll.c\nstatic int ep_insert(struct eventpoll *ep, const struct epoll_event *event,\n             struct file *tfile, int fd, int full_check)\n{\n    ...\n    ep_rbtree_insert(ep, epi);\n    ...\n}\n\n\/* \u662f\u771f\u6b63\u5411\u7ea2\u9ed1\u6811\u4e2d\u63d2\u5165\u8282\u70b9\u7684\u51fd\u6570 *\/\nstatic void ep_rbtree_insert(struct eventpoll *ep, struct epitem *epi)\n{\n    int kcmp;\n    struct rb_node **p = &amp;ep-&gt;rbr.rb_root.rb_node, *parent = NULL;\n    struct epitem *epic;\n    bool leftmost = true;\n\n    \/* \u904d\u5386\u7ea2\u9ed1\u6811\uff0c\u627e\u5230\u5408\u9002\u7684\u63d2\u5165\u4f4d\u7f6e *\/\n    while (*p) {\n        parent = *p;\n        \/* \u901a\u8fc7\u7236\u8282\u70b9\u83b7\u53d6\u5bf9\u5e94\u7684 epitem \u7ed3\u6784\u4f53 *\/\n        epic = rb_entry(parent, struct epitem, rbn);\n        \/* \u6bd4\u8f83\u5f53\u524d\u8282\u70b9\u4e0e\u8981\u63d2\u5165\u7684\u8282\u70b9 *\/\n        kcmp = ep_cmp_ffd(&amp;epi-&gt;ffd, &amp;epic-&gt;ffd); \n        \/* \u5982\u679c\u8981\u63d2\u5165\u8282\u70b9\u7684\u5173\u952e\u5b57\u5927\u4e8e\u5f53\u524d\u8282\u70b9\uff0c\u5219\u5411\u53f3\u5b50\u6811\u67e5\u627e,\u5426\u5219\u5411\u5de6\u5b50\u6811\u67e5\u627e *\/\n        if (kcmp &gt; 0) {\n            p = &amp;parent-&gt;rb_right;\n            leftmost = false; \/\/ \u6807\u8bb0\u4e0d\u662f\u6700\u5de6\u4fa7\u8282\u70b9\n        } else {\n            p = &amp;parent-&gt;rb_left;\n        }\n    }\n\n    \/* \u5c06\u65b0\u8282\u70b9\u94fe\u63a5\u5230\u7236\u8282\u70b9\u4e0a\uff0c\u5e76\u91cd\u65b0\u5e73\u8861\u7ea2\u9ed1\u6811 *\/ \n    rb_link_node(&amp;epi-&gt;rbn, parent, p);\n    rb_insert_color_cached(&amp;epi-&gt;rbn, &amp;ep-&gt;rbr, leftmost);\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6838\u5fc3\u601d\u60f3<\/strong><br>\u91c7\u7528\u6df1\u5ea6\u4f18\u5148\u7684\u7b56\u7565\uff0c\u904d\u5386\u7ea2\u9ed1\u6811\u627e\u5230\u76ee\u6807\u8282\u70b9\uff0c\u7136\u540e\u5c06\u8282\u70b9\u63d2\u5165<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2. ep_remove\u51fd\u6570<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u4ece\u7ea2\u9ed1\u6811\u4e2d\u5220\u9664\u8282\u70b9<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6838\u5fc3\u903b\u8f91\u5982\u4e0b<\/strong><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u4e0b\u6587\u4ee3\u7801\u5df2\u683c\u5f0f\u5316\u5904\u7406\uff0c\u5e76\u9002\u5f53\u7b80\u5316\u53ea\u4fdd\u7559\u6838\u5fc3\u903b\u8f91<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ linux-5.4\/fs\/eventpoll.c\n\/*\n * Removes a \"struct epitem\" from the eventpoll RB tree and deallocates\n * all the associated resources. Must be called with \"mtx\" held.\n *\/\nstatic int ep_remove(struct eventpoll *ep, struct epitem *epi)\n{\n    \/* \u79fb\u9664\u8f6e\u8be2\u7b49\u5f85\u961f\u5217\u94a9\u5b50 *\/\n    ep_unregister_pollwait(ep, epi); \n\n    list_del_rcu(&amp;epi-&gt;fllink); \/\/ \u4eceepoll\u94a9\u5b50\u5217\u8868\u4e2d\u79fb\u9664\u5f53\u524depitem\n\n    \/* \u4ece\u7ea2\u9ed1\u6811\u4e2d\u79fb\u9664\u5f53\u524depitem *\/\n    rb_erase_cached(&amp;epi-&gt;rbn, &amp;ep-&gt;rbr); \n\n    \/**\n     * \u68c0\u67e5\u5f53\u524depitem\u662f\u5426\u5df2\u7ecf\u94fe\u63a5\u5230\u67d0\u4e2a\u94fe\u8868\u4e2d\n     * \u5982\u679c\u5df2\u94fe\u63a5\uff0c\u5219\u4ece\u4e8b\u4ef6\u8f6e\u8be2\u7684\u94fe\u8868\u4e2d\u79fb\u9664\n     *\/\n    if (ep_is_linked(epi)) \n        list_del_init(&amp;epi-&gt;rdllink); \n\n    return 0;\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">3. ep_modify\u51fd\u6570<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u4fee\u6539\u8282\u70b9<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6838\u5fc3\u903b\u8f91\u5982\u4e0b<\/strong><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u4e0b\u6587\u4ee3\u7801\u5df2\u683c\u5f0f\u5316\u5904\u7406\uff0c\u5e76\u9002\u5f53\u7b80\u5316\u53ea\u4fdd\u7559\u6838\u5fc3\u903b\u8f91<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ linux-5.4\/fs\/eventpoll.c\n\/*\n * Modify the interest event mask by dropping an event if the new mask\n * has a match in the current file status. Must be called with \"mtx\" held.\n *\/\nstatic int ep_modify(struct eventpoll *ep, struct epitem *epi,\n             const struct epoll_event *event)\n{\n    int pwake = 0;\n    poll_table pt;\n\n    lockdep_assert_irqs_enabled();\n\n    init_poll_funcptr(&amp;pt, NULL);\n\n    epi-&gt;event.events = event-&gt;events;\n    epi-&gt;event.data = event-&gt;data;\n    \/*\n     * \u68c0\u67e5\u5f53\u524d\u8282\u70b9\u662f\u5426\u8bbe\u7f6e\u4e86EPOLLWAKEUP,\u5982\u679c\u8bbe\u7f6e\u4e86,\u4e14\u5f53\u524d epitem \u6ca1\u6709\u5524\u9192\u6e90,\u5219\u521b\u5efa\u4e00\u4e2a;\n     * \u5982\u679c\u672a\u8bbe\u7f6e,\u4e14\u5f53\u524d\u6709\u5524\u9192\u6e90,\u5219\u9500\u6bc1\u5b83\n     *\/\n    if (epi-&gt;event.events &amp; EPOLLWAKEUP) {\n        if (!ep_has_wakeup_source(epi))\n            ep_create_wakeup_source(epi);\n    } else if (ep_has_wakeup_source(epi)) {\n        ep_destroy_wakeup_source(epi);\n    }\n\n    \/* \u901a\u8fc7vfs_poll\u6216\u68c0\u67e5rdllink\u94fe\u8868\uff0c\u5224\u65ad\u5f53\u524d\u8282\u70b9\u662f\u5426\u51c6\u5907\u5c31\u7eea *\/\n    if (ep_item_poll(epi, &amp;pt, 1)) {\n        \/* \u68c0\u67e5\u5f53\u524d\u63a5\u8282\u70b9\u662f\u5426\u94fe\u63a5\u5230rdllink\u94fe\u8868\u4e0a *\/\n        if (!ep_is_linked(epi)) {\n            list_add_tail(&amp;epi-&gt;rdllink, &amp;ep-&gt;rdllist);\n            \/* \u4fdd\u6301epoll\u6d3b\u8dc3 *\/\n            ep_pm_stay_awake(epi);\n            if (waitqueue_active(&amp;ep-&gt;wq))\n                wake_up(&amp;ep-&gt;wq);\n            if (waitqueue_active(&amp;ep-&gt;poll_wait))\n                pwake++;\n        }\n    }\n\n    if (pwake)\n        ep_poll_safewake(&amp;ep-&gt;poll_wait);\n\n    return 0;\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">4. ep_find\u51fd\u6570<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u5728\u7ea2\u9ed1\u6811\u4e2d\u67e5\u627e\u8282\u70b9<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6e90\u4ee3\u7801\u5982\u4e0b<\/strong><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u9664\u6ce8\u91ca\u5916\uff0c\u6240\u6709\u4ee3\u7801\u5747\u672a\u5220\u6539<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ linux-5.4\/fs\/eventpoll.c\nstatic struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd)\n{\n    int kcmp;\n    struct rb_node *rbp;\n    struct epitem *epi, *epir = NULL;\n    struct epoll_filefd ffd;\n\n    \/* \u8bbe\u7f6eepoll_filefd\u7ed3\u6784\u4f53\uff0c\u7528\u4e8e\u6bd4\u8f83\u67e5\u627e *\/\n    ep_set_ffd(&amp;ffd, file, fd);\n\n    \/* \u904d\u5386\u7ea2\u9ed1\u6811 *\/\n    for (rbp = ep-&gt;rbr.rb_root.rb_node; rbp; ) {\n        \/* \u901a\u8fc7\u7236\u8282\u70b9\u83b7\u53d6\u5bf9\u5e94\u7684 epitem \u7ed3\u6784\u4f53 *\/\n        epi = rb_entry(rbp, struct epitem, rbn);\n        \/* \u6bd4\u8f83\u5f53\u524d\u8282\u70b9\u4e0e\u8981\u63d2\u5165\u7684\u8282\u70b9 *\/\n        kcmp = ep_cmp_ffd(&amp;ffd, &amp;epi-&gt;ffd);\n         \/* \u5982\u679c\u8981\u63d2\u5165\u8282\u70b9\u7684\u5173\u952e\u5b57\u5927\u4e8e\u5f53\u524d\u8282\u70b9\uff0c\u5219\u5411\u53f3\u5b50\u6811\u67e5\u627e,\u5426\u5219\u5411\u5de6\u5b50\u6811\u67e5\u627e *\/\n        if (kcmp &gt; 0)\n            rbp = rbp-&gt;rb_right;\n        else if (kcmp &lt; 0)\n            rbp = rbp-&gt;rb_left;\n        else {\n            epir = epi;\n            break;\n        }\n    }\n\n    return epir;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6838\u5fc3\u601d\u60f3<\/strong><br>\u91c7\u7528\u6df1\u5ea6\u4f18\u5148\u7684\u7b56\u7565\uff0c\u904d\u5386\u7ea2\u9ed1\u6811\u627e\u5230\u76ee\u6807\u8282\u70b9<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u516b\u3001\u9762\u5411VFS\u90e8\u5206\u7684\u63a5\u53e3<\/h2>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u672c\u7ae0\u540e\u7eed\u5b8c\u5584\u8865\u5145<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\"><code>eventpoll_fops<\/code>\u7ed3\u6784\u4f53\u4e2d\u6ce8\u518c\u4e86\u6570\u4e2a\u7528\u4e8e\u9762\u5411<code>VFS<\/code>\u7684\u63a5\u53e3\uff0c\u5728<code>ep_alloc<\/code>\u4e2d\u521d\u59cb\u5316\u65f6\u4f1a\u88ab\u4f7f\u7528<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u6e90\u4ee3\u7801\u5982\u4e0b<\/strong><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u7b14\u8005\u6ce8\uff1a\u6240\u6709\u4ee3\u7801\u5747\u672a\u5220\u6539<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ linux-5.4\/fs\/eventpoll.c\n\n\/* File callbacks that implement the eventpoll file behaviour *\/\nstatic const struct file_operations eventpoll_fops = {\n#ifdef CONFIG_PROC_FS\n    .show_fdinfo    = ep_show_fdinfo,\n#endif\n    .release    = ep_eventpoll_release,\n    .poll        = ep_eventpoll_poll,\n    .llseek        = noop_llseek,\n};<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">\u4e5d\u3001\u5176\u4ed6\u6a21\u5757\u7684poll\u65b9\u6cd5\u5b9e\u73b0<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1. \u9a71\u52a8\u5c42\u9762\u5bf9\u6587\u4ef6\u7cfb\u7edf\u7684\u76d1\u542c<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>file_operations-&gt;poll\u63a5\u53e3<\/strong><br><strong>\u51fd\u6570\u58f0\u660e<\/strong><br>\u5728<code>linux-5.4\\include\\linux\\fs.h<\/code>\u4e2d\u53ef\u4ee5\u770b\u5230<code>struct file_operations<\/code>\u7684\u5b9a\u4e49<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define __bitwise __attribute__((bitwise))\ntypedef unsigned __bitwise __poll_t;\n\nstruct file_operations {\n    ...\n    \/* read\u610f\u4e3a\u8bfb\u3001write\u610f\u4e3a\u5199\u3001poll\u610f\u4e3a\u68c0\u6d4b\uff0c\u63a2\u8be2 *\/\n    ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);\n    ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);\n    __poll_t (*poll) (struct file *, struct poll_table_struct *);\n    ...\n} __randomize_layout;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u51fd\u6570\u5b9e\u73b0<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>struct file_operations<\/code>\u4e2d\u7684<code>__poll_t<\/code>\u662f\u5728\u9a71\u52a8\u4ee3\u7801\u4e2d\u5b9e\u73b0\uff0c\u4e0d\u540c\u9a71\u52a8\u4ee3\u7801\u5b9e\u73b0\u65b9\u5f0f\u4e0d\u540c\u3002\u4f46\u90fd\u4f1a\u8c03\u7528<code>poll_wait()<\/code>\u51fd\u6570<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u5728\u6b64\u5904\u5217\u51fa\u4f8b\u5b50<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u5728<code>linux-5.4\\arch\\powerpc\\platforms\\powernv\\opal-prd.c<\/code>\u4e2d\u53ef\u4ee5\u627e\u5230<code>OPAL<\/code>\u7684\u9a71\u52a8\u5bf9\u4e8e<code>poll<\/code>\u7684\u5b9e\u73b0<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static const struct file_operations opal_prd_fops = {\n    ...\n    .poll        = opal_prd_poll,\n    ...\n};\n\nstatic __poll_t opal_prd_poll(struct file *file,\n        struct poll_table_struct *wait)\n{\n    poll_wait(file, &amp;opal_prd_msg_wait, wait);\n\n    if (!opal_msg_queue_empty())\n        return EPOLLIN | EPOLLRDNORM;\n\n    return 0;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u5728<code>linux-5.4\\arch\\powerpc\\kernel\\rtasd.c<\/code>\u4e2d\u53ef\u4ee5\u627e\u5230<code>RTASD<\/code>\u7684\u9a71\u52a8\u5bf9\u4e8e<code>poll<\/code>\u7684\u5b9e\u73b0<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>static __poll_t rtas_log_poll(struct file *file, poll_table * wait)\n{\n    poll_wait(file, &amp;rtas_log_wait, wait);\n    if (rtas_log_size)\n        return EPOLLIN | EPOLLRDNORM;\n    return 0;\n}\n\nstatic const struct file_operations proc_rtas_log_operations = {\n    ...\n    .poll =        rtas_log_poll,\n    ...\n};<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u53ef\u4ee5\u770b\u5230\u4e0d\u540c\u7684\u9a71\u52a8\u4ee3\u7801\u4e2d\u90fd\u8c03\u7528\u4e86<code>poll_wait()<\/code>\uff0c\u628a\u5f53\u524d\u8fdb\u7a0b\u52a0\u5165\u5230\u9a71\u52a8\u91cc\u81ea\u5b9a\u4e49\u7684\u7b49\u5f85\u961f\u5217\u4e0a\uff0c\u5f53\u9a71\u52a8\u4e8b\u4ef6\u5c31\u7eea\u540e\uff0c\u5c31\u53ef\u4ee5\u5728\u9a71\u52a8\u91cc\u81ea\u5b9a\u4e49\u7684\u7b49\u5f85\u961f\u5217\u4e0a\u5524\u9192\u8c03\u7528<code>poll<\/code>\u7684\u8fdb\u7a0b\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2. \u5185\u6838\u7b49\u5f85\u961f\u5217<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u7b49\u5f85\u961f\u5217\u57fa\u672c\u6d41\u7a0b\u5982\u4e0b<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u5728<code>select<\/code>\u548c<code>poll<\/code>\u6a21\u5757\u4e2d\u81ea\u5df1\u5b9e\u73b0\u4e86<code>pollwake<\/code>\u51fd\u6570\u4f5c\u4e3a\u7b49\u5f85\u961f\u5217\u56de\u8c03<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/\u9a71\u52a8\u6587\u4ef6\u76d1\u542c\u56de\u8c03-4096x1200.jpg'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" width=\"4096\" height=\"1200\" data-original=\"https:\/\/www.garfield-blog.top\/wp-content\/uploads\/2026\/05\/\u9a71\u52a8\u6587\u4ef6\u76d1\u542c\u56de\u8c03-4096x1200.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" class=\"wp-image-528\"  sizes=\"auto, (max-width: 4096px) 100vw, 4096px\" \/><\/div><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">\u5341\u3001epoll\u4e0eselect\u3001poll\u7684\u5bf9\u6bd4<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>1) \u7528\u6237\u6001\u5c06\u6587\u4ef6\u63cf\u8ff0\u7b26\u4f20\u5165\u5185\u6838\u7684\u65b9\u5f0f<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>select<\/code>\uff1a\u521b\u5efa<code>3<\/code>\u4e2a\u6587\u4ef6\u63cf\u8ff0\u7b26\u96c6\u5e76\u62f7\u8d1d\u5230\u5185\u6838\u4e2d\uff0c\u5206\u522b\u76d1\u542c\u8bfb\u3001\u5199\u3001\u5f02\u5e38\u52a8\u4f5c\u3002\u8fd9\u91cc\u53d7\u5230\u5355\u4e2a\u8fdb\u7a0b\u53ef\u4ee5\u6253\u5f00\u7684<code>fd<\/code>\u6570\u91cf\u9650\u5236\uff0c\u9ed8\u8ba4\u662f<code>1024<\/code><\/li>\n\n\n\n<li><code>poll<\/code>\uff1a\u5c06\u4f20\u5165\u7684<code>struct pollfd<\/code>\u7ed3\u6784\u4f53\u6570\u7ec4\u62f7\u8d1d\u5230\u5185\u6838\u4e2d\u8fdb\u884c\u76d1\u542c<\/li>\n\n\n\n<li><code>epoll<\/code>\uff1a\u6267\u884c<code>epoll_create<\/code>\u4f1a\u5728\u5185\u6838\u7684\u9ad8\u901f<code>cache<\/code>\u533a\u4e2d\u5efa\u7acb\u4e00\u9897\u7ea2\u9ed1\u6811\u4ee5\u53ca\u5c31\u7eea\u94fe\u8868(\u8be5\u94fe\u8868\u5b58\u50a8\u5df2\u7ecf\u5c31\u7eea\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26)\u3002\u63a5\u7740\u7528\u6237\u6267\u884c\u7684<code>epoll_ctl<\/code>\u51fd\u6570\u6dfb\u52a0\u6587\u4ef6\u63cf\u8ff0\u7b26\u4f1a\u5728\u7ea2\u9ed1\u6811\u4e0a\u589e\u52a0\u76f8\u5e94\u7684\u7ed3\u70b9<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>2) \u5185\u6838\u6001\u68c0\u6d4b\u6587\u4ef6\u63cf\u8ff0\u7b26\u8bfb\u5199\u72b6\u6001\u7684\u65b9\u5f0f<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>select<\/code>\uff1a\u91c7\u7528\u8f6e\u8be2\u65b9\u5f0f\uff0c\u904d\u5386\u6240\u6709<code>fd<\/code>\uff0c\u6700\u540e\u8fd4\u56de\u4e00\u4e2a\u63cf\u8ff0\u7b26\u8bfb\u5199\u64cd\u4f5c\u662f\u5426\u5c31\u7eea\u7684<code>mask<\/code>\u63a9\u7801\uff0c\u6839\u636e\u8fd9\u4e2a\u63a9\u7801\u7ed9<code>fd_set<\/code>\u8d4b\u503c<\/li>\n\n\n\n<li><code>poll<\/code>\uff1a\u540c\u6837\u91c7\u7528\u8f6e\u8be2\u65b9\u5f0f\uff0c\u67e5\u8be2\u6bcf\u4e2a<code>fd<\/code>\u7684\u72b6\u6001\uff0c\u5982\u679c\u5c31\u7eea\u5219\u5728\u7b49\u5f85\u961f\u5217\u4e2d\u52a0\u5165\u4e00\u9879\u5e76\u7ee7\u7eed\u904d\u5386<\/li>\n\n\n\n<li><code>epoll<\/code>\uff1a\u91c7\u7528\u56de\u8c03\u673a\u5236\u3002\u5728\u6267\u884c<code>epoll_ctl<\/code>\u7684<code>add<\/code>\u64cd\u4f5c\u65f6\uff0c\u4e0d\u4ec5\u5c06\u6587\u4ef6\u63cf\u8ff0\u7b26\u653e\u5230\u7ea2\u9ed1\u6811\u4e0a\uff0c\u800c\u4e14\u4e5f\u6ce8\u518c\u4e86\u56de\u8c03\u51fd\u6570\uff0c\u5185\u6838\u5728\u68c0\u6d4b\u5230\u67d0\u6587\u4ef6\u63cf\u8ff0\u7b26\u53ef\u8bfb\/\u53ef\u5199\u65f6\u4f1a\u8c03\u7528\u56de\u8c03\u51fd\u6570\uff0c\u8be5\u56de\u8c03\u51fd\u6570\u5c06\u6587\u4ef6\u63cf\u8ff0\u7b26\u653e\u5728\u5c31\u7eea\u94fe\u8868\u4e2d<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>3) \u627e\u5230\u5c31\u7eea\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26\u5e76\u4f20\u9012\u7ed9\u7528\u6237\u6001\u7684\u65b9\u5f0f<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>select<\/code>\uff1a\u5c06\u4e4b\u524d\u4f20\u5165\u7684<code>fd_set<\/code>\u62f7\u8d1d\u4f20\u51fa\u5230\u7528\u6237\u6001\u5e76\u8fd4\u56de\u5c31\u7eea\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26\u603b\u6570\u3002\u7528\u6237\u6001\u5e76\u4e0d\u77e5\u9053\u662f\u54ea\u4e9b\u6587\u4ef6\u63cf\u8ff0\u7b26\u5904\u4e8e\u5c31\u7eea\u6001\uff0c\u9700\u8981\u904d\u5386\u6765\u5224\u65ad<\/li>\n\n\n\n<li><code>poll<\/code>\uff1a\u5c06\u4e4b\u524d\u4f20\u5165\u7684<code>fd<\/code>\u6570\u7ec4\u62f7\u8d1d\u4f20\u51fa\u7528\u6237\u6001\u5e76\u8fd4\u56de\u5c31\u7eea\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26\u603b\u6570\u3002\u7528\u6237\u6001\u5e76\u4e0d\u77e5\u9053\u662f\u54ea\u4e9b\u6587\u4ef6\u63cf\u8ff0\u7b26\u5904\u4e8e\u5c31\u7eea\u6001\uff0c\u9700\u8981\u904d\u5386\u6765\u5224\u65ad<\/li>\n\n\n\n<li><code>epoll<\/code>\uff1a<code>epoll_wait<\/code>\u53ea\u7528\u89c2\u5bdf\u5c31\u7eea\u94fe\u8868\u4e2d\u6709\u65e0\u6570\u636e\u5373\u53ef\uff0c\u6700\u540e\u5c06\u94fe\u8868\u7684\u6570\u636e\u8fd4\u56de\u7ed9\u6570\u7ec4\u5e76\u8fd4\u56de\u5c31\u7eea\u7684\u6570\u91cf\u3002\u5185\u6838\u5c06\u5c31\u7eea\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26\u653e\u5728\u4f20\u5165\u7684\u6570\u7ec4\u4e2d\uff0c\u6240\u4ee5\u53ea\u7528\u904d\u5386\u4f9d\u6b21\u5904\u7406\u5373\u53ef\u3002\u8fd9\u91cc\u8fd4\u56de\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26\u662f\u901a\u8fc7<code>mmap<\/code>\u8ba9\u5185\u6838\u548c\u7528\u6237\u7a7a\u95f4\u5171\u4eab\u540c\u4e00\u5757\u5185\u5b58\u5b9e\u73b0\u4f20\u9012\u7684\uff0c\u51cf\u5c11\u4e86\u4e0d\u5fc5\u8981\u7684\u62f7\u8d1d<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>4) \u91cd\u590d\u76d1\u542c\u7684\u5904\u7406\u65b9\u5f0f<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>select<\/code>\uff1a\u5c06\u65b0\u7684\u76d1\u542c\u6587\u4ef6\u63cf\u8ff0\u7b26\u96c6\u5408\u62f7\u8d1d\u4f20\u5165\u5185\u6838\u4e2d\uff0c\u7ee7\u7eed\u4ee5\u4e0a\u6b65\u9aa4<\/li>\n\n\n\n<li><code>poll<\/code>\uff1a\u5c06\u65b0\u7684<code>struct pollfd<\/code>\u7ed3\u6784\u4f53\u6570\u7ec4\u62f7\u8d1d\u4f20\u5165\u5185\u6838\u4e2d\uff0c\u7ee7\u7eed\u4ee5\u4e0a\u6b65\u9aa4<\/li>\n\n\n\n<li><code>epoll<\/code>\uff1a\u65e0\u9700\u91cd\u65b0\u6784\u5efa\u7ea2\u9ed1\u6811\uff0c\u76f4\u63a5\u6cbf\u7528\u5df2\u5b58\u5728\u7684\u5373\u53ef<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">\u5341\u4e00\u3001\u603b\u7ed3<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>epoll\u66f4\u9ad8\u6548\u7684\u539f\u56e0<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1\uff09<code>select<\/code>\u548c<code>poll<\/code>\u7684\u52a8\u4f5c\u57fa\u672c\u4e00\u81f4\uff0c\u53ea\u662f<code>poll<\/code>\u91c7\u7528\u94fe\u8868\u6765\u8fdb\u884c\u6587\u4ef6\u63cf\u8ff0\u7b26\u7684\u5b58\u50a8\uff0c\u800c<code>select<\/code>\u91c7\u7528fd\u6807\u6ce8\u4f4d\u6765\u5b58\u653e\uff0c\u6240\u4ee5<code>select<\/code>\u4f1a\u53d7\u5230\u6700\u5927\u8fde\u63a5\u6570\u7684\u9650\u5236\uff0c\u800c<code>poll<\/code>\u4e0d\u4f1a<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">2\uff09<code>select<\/code>\u3001<code>poll<\/code>\u3001<code>epoll<\/code>\u867d\u7136\u90fd\u4f1a\u8fd4\u56de\u5c31\u7eea\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26\u6570\u91cf\u3002\u4f46\u662f<code>select<\/code>\u548c<code>poll<\/code>\u5e76\u4e0d\u4f1a\u660e\u786e\u6307\u51fa\u662f\u54ea\u4e9b\u6587\u4ef6\u63cf\u8ff0\u7b26\u5c31\u7eea\uff0c\u800c<code>epoll<\/code>\u4f1a\u3002\u9020\u6210\u7684\u533a\u522b\u5c31\u662f\uff0c\u7cfb\u7edf\u8c03\u7528\u8fd4\u56de\u540e\uff0c\u8c03\u7528<code>select<\/code>\u548c<code>poll<\/code>\u7684\u7a0b\u5e8f\u9700\u8981\u904d\u5386\u76d1\u542c\u7684\u6574\u4e2a\u6587\u4ef6\u63cf\u8ff0\u7b26\u627e\u5230\u662f\u8c01\u5904\u4e8e\u5c31\u7eea\uff0c\u800cepoll\u5219\u76f4\u63a5\u5904\u7406\u5373\u53ef<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">3\uff09<code>select<\/code>\u3001<code>poll<\/code>\u90fd\u9700\u8981\u5c06\u6709\u5173\u6587\u4ef6\u63cf\u8ff0\u7b26\u7684\u6570\u636e\u7ed3\u6784\u62f7\u8d1d\u8fdb\u5185\u6838\uff0c\u6700\u540e\u518d\u62f7\u8d1d\u51fa\u6765\u3002\u800c<code>epoll<\/code>\u521b\u5efa\u7684\u6709\u5173\u6587\u4ef6\u63cf\u8ff0\u7b26\u7684\u6570\u636e\u7ed3\u6784\u672c\u8eab\u5c31\u5b58\u4e8e\u5185\u6838\u6001\u4e2d\uff0c\u7cfb\u7edf\u8c03\u7528\u8fd4\u56de\u65f6\u5229\u7528<code>mmap()<\/code>\u6587\u4ef6\u6620\u5c04\u5185\u5b58\u52a0\u901f\u4e0e\u5185\u6838\u7a7a\u95f4\u7684\u6d88\u606f\u4f20\u9012\uff1a\u5373<code>epoll<\/code>\u4f7f\u7528<code>mmap<\/code>\u51cf\u5c11\u590d\u5236\u5f00\u9500<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">4\uff09<code>select<\/code>\u3001<code>poll<\/code>\u91c7\u7528\u8f6e\u8be2\u7684\u65b9\u5f0f\u6765\u68c0\u67e5\u6587\u4ef6\u63cf\u8ff0\u7b26\u662f\u5426\u5904\u4e8e\u5c31\u7eea\u6001\uff0c\u800c<code>epoll<\/code>\u91c7\u7528\u56de\u8c03\u673a\u5236\u3002\u9020\u6210\u7684\u7ed3\u679c\u5c31\u662f\uff0c\u968f\u7740<code>fd<\/code>\u7684\u589e\u52a0\uff0c<code>select<\/code>\u548c<code>poll<\/code>\u7684\u6548\u7387\u4f1a\u7ebf\u6027\u964d\u4f4e\uff0c\u800c<code>epoll<\/code>\u4e0d\u4f1a\u53d7\u5230\u592a\u5927\u5f71\u54cd\uff0c\u9664\u975e\u6d3b\u8dc3\u7684<code>socket<\/code>\u5f88\u591a<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">5\uff09<code>epoll<\/code>\u7684\u8fb9\u7f18\u89e6\u53d1\u6a21\u5f0f\u6548\u7387\u9ad8\uff0c\u7cfb\u7edf\u4e0d\u4f1a\u5145\u65a5\u5927\u91cf\u4e0d\u5173\u5fc3\u7684\u5c31\u7eea\u6587\u4ef6\u63cf\u8ff0\u7b26<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u867d\u7136epoll\u7684\u6027\u80fd\u6700\u597d\uff0c\u4f46\u662f\u5728\u8fde\u63a5\u6570\u5c11\u5e76\u4e14\u8fde\u63a5\u90fd\u5341\u5206\u6d3b\u8dc3\u7684\u60c5\u51b5\u4e0b\uff0cselect\u548cpoll\u7684\u6027\u80fd\u53ef\u80fd\u6bd4epoll\u597d\uff0c\u6bd5\u7adfepoll\u7684\u901a\u77e5\u673a\u5236\u9700\u8981\u5f88\u591a\u51fd\u6570\u56de\u8c03<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">\u53c2\u8003\u6587\u6863<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/cloud.tencent.com\/developer\/article\/1964472\">\u56fe\u89e3 | \u6df1\u5165\u63ed\u79d8 epoll \u662f\u5982\u4f55\u5b9e\u73b0 IO \u591a\u8def\u590d\u7528\u7684\uff01-\u817e\u8baf\u4e91\u5f00\u53d1\u8005\u793e\u533a-\u817e\u8baf\u4e91 (tencent.com)<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/my.oschina.net\/alchemystar\/blog\/3008840\">\u4ecelinux\u6e90\u7801\u770bepoll &#8211; \u65e0\u6bc1\u7684\u6e56\u5149-Al\u7684\u4e2a\u4eba\u7a7a\u95f4 &#8211; OSCHINA &#8211; \u4e2d\u6587\u5f00\u6e90\u6280\u672f\u4ea4\u6d41\u793e\u533a<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/github.com\/torvalds\/linux\/releases\/tag\/v5.4\">Linux 5.4\u6e90\u7801<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>epoll\u539f\u7406\u53ca\u5b9e\u73b0 \u4e00\u3001 \u53d1\u5c55\u5386\u53f2 API \u53d1\u5e03\u7684\u65f6\u95f4\u7ebf \u4e0b\u6587\u4e2d\u5217\u51fa\u4e86\u7f51\u7edc IO\u4e2d\uff0c\u5404\u4e2aapi\u7684\u53d1\u5e03\u65f6\u95f4\u7ebf  [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-509","post","type-post","status-publish","format-standard","hentry","category-source-code-analysis"],"_links":{"self":[{"href":"https:\/\/www.garfield-blog.top\/index.php?rest_route=\/wp\/v2\/posts\/509","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.garfield-blog.top\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.garfield-blog.top\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.garfield-blog.top\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.garfield-blog.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=509"}],"version-history":[{"count":7,"href":"https:\/\/www.garfield-blog.top\/index.php?rest_route=\/wp\/v2\/posts\/509\/revisions"}],"predecessor-version":[{"id":543,"href":"https:\/\/www.garfield-blog.top\/index.php?rest_route=\/wp\/v2\/posts\/509\/revisions\/543"}],"wp:attachment":[{"href":"https:\/\/www.garfield-blog.top\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=509"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.garfield-blog.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=509"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.garfield-blog.top\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=509"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}