Update Socket.md

补充 select/poll 与 epoll 的对比示意图。
This commit is contained in:
CyC2018
2026-10-25 19:34:21 +08:00
parent f6c77c1cab
commit b3e943b5e6
3 changed files with 89 additions and 0 deletions
+2
View File
@@ -234,6 +234,8 @@ epoll_ctl() 用于向内核注册新的描述符或者是改变某个文件描
从上面的描述可以看出,epoll 只需要将描述符从进程缓冲区向内核缓冲区拷贝一次,并且进程不需要通过轮询来获得事件完成的描述符。
<div align="center"> <img src="pics/epoll.png" width="600px"/> </div><br>
epoll 仅适用于 Linux OS。
epoll 比 select 和 poll 更加灵活而且没有描述符数量限制。
Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

+87
View File
@@ -0,0 +1,87 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="330" viewBox="0 0 640 330">
<style>
text { font-family: "PingFang SC", "Microsoft YaHei", Helvetica, Arial, sans-serif; fill: #666; font-size: 12px; }
.title { font-weight: bold; font-size: 15px; fill: #777; text-anchor: middle; }
.b { font-weight: bold; }
.c { text-anchor: middle; }
.e { text-anchor: end; }
.note { fill: #C0605A; }
.ok { fill: #6A9F68; }
.sub { font-size: 11px; fill: #888; }
.mono { font-family: Menlo, Consolas, monospace; }
.arrow { stroke: #666; stroke-width: 1.3; fill: none; marker-end: url(#a); }
.red { stroke: #C0605A; marker-end: url(#r); }
.green { stroke: #6A9F68; marker-end: url(#g); }
.dash { stroke-dasharray: 5 4; }
.line { stroke: #666; stroke-width: 1.3; fill: none; }
.frame { fill: none; stroke: #999; stroke-width: 1; stroke-dasharray: 4 3; }
.shadow { fill: #C0C0C0; }
</style>
<defs>
<marker id="a" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M1,1 L9,5 L1,9" fill="none" stroke="#666" stroke-width="1.6"/>
</marker>
<marker id="r" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M1,1 L9,5 L1,9" fill="none" stroke="#C0605A" stroke-width="1.6"/>
</marker>
<marker id="g" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M1,1 L9,5 L1,9" fill="none" stroke="#6A9F68" stroke-width="1.6"/>
</marker>
</defs>
<rect width="100%" height="100%" fill="#FFFFFF"/>
<text x="320" y="28" class="title">select / poll 与 epoll</text>
<rect x="20" y="50" width="290" height="265" rx="8" class="frame"/>
<text x="30" y="68" class="b">select / poll</text>
<rect x="98" y="83" width="140" height="34" rx="6" class="shadow"/>
<rect x="95" y="80" width="140" height="34" rx="6" fill="#B0E3E6"/>
<text x="165" y="101.5" class="b c">用户进程</text>
<line x1="30" y1="150" x2="300" y2="150" class="line dash"/>
<text x="300" y="143" class="sub e">用户态</text>
<text x="300" y="163" class="sub e">内核态</text>
<rect x="330" y="50" width="290" height="265" rx="8" class="frame"/>
<text x="340" y="68" class="b">epoll</text>
<rect x="408" y="83" width="140" height="34" rx="6" class="shadow"/>
<rect x="405" y="80" width="140" height="34" rx="6" fill="#B0E3E6"/>
<text x="475" y="101.5" class="b c">用户进程</text>
<line x1="340" y1="150" x2="610" y2="150" class="line dash"/>
<text x="610" y="143" class="sub e">用户态</text>
<text x="610" y="163" class="sub e">内核态</text>
<line x1="110" y1="117" x2="110" y2="200" class="arrow "/>
<text x="104" y="180" class="e sub">每次调用复制</text>
<text x="104" y="194" class="e sub">全部描述符</text>
<rect x="73" y="206" width="160" height="40" rx="6" class="shadow"/>
<rect x="70" y="203" width="160" height="40" rx="6" fill="#B1DDF0"/>
<text x="150" y="221" class="b c">遍历全部描述符</text>
<text x="150" y="236" class="sub c">检查是否就绪</text>
<line x1="195" y1="200" x2="195" y2="117" class="arrow "/>
<text x="200" y="180" class="sub">返回后进程</text>
<text x="200" y="194" class="sub">再遍历一次</text>
<text x="165" y="290" class="c note">每次调用都是 O(N)</text>
<line x1="390" y1="117" x2="390" y2="200" class="arrow "/>
<text x="397" y="180" class="sub mono">epoll_ctl()</text>
<text x="397" y="194" class="sub">注册一次</text>
<line x1="400" y1="215" x2="370" y2="245" class="line"/>
<line x1="400" y1="215" x2="430" y2="245" class="line"/>
<line x1="370" y1="245" x2="355" y2="275" class="line"/>
<line x1="370" y1="245" x2="385" y2="275" class="line"/>
<line x1="430" y1="245" x2="415" y2="275" class="line"/>
<circle cx="400" cy="215" r="9" fill="#61646B"/>
<circle cx="370" cy="245" r="9" fill="#C0605A"/>
<circle cx="430" cy="245" r="9" fill="#61646B"/>
<circle cx="355" cy="275" r="9" fill="#61646B"/>
<circle cx="385" cy="275" r="9" fill="#61646B"/>
<circle cx="415" cy="275" r="9" fill="#C0605A"/>
<text x="400" y="300" class="c sub">红黑树:已注册描述符</text>
<rect x="535" y="210" width="50" height="20" rx="3" fill="#F3D9A4"/>
<rect x="535" y="238" width="50" height="20" rx="3" fill="#F3D9A4"/>
<line x1="560" y1="230" x2="560" y2="237" class="arrow "/>
<rect x="535" y="266" width="50" height="20" rx="3" fill="#F3D9A4"/>
<line x1="560" y1="258" x2="560" y2="265" class="arrow "/>
<text x="560" y="297" class="c sub">就绪链表</text>
<path d="M430,245 C470,245 490,220 532,220" class="arrow dash"/>
<text x="478" y="267" class="c sub">就绪时回调</text>
<line x1="560" y1="202" x2="560" y2="117" class="arrow "/>
<text x="553" y="180" class="e sub mono">epoll_wait()</text>
<text x="553" y="194" class="e sub">只取就绪的</text>
</svg>

After

Width:  |  Height:  |  Size: 4.9 KiB