golang网络轮询器
网络轮询器
大部分服务都是I/O密集型的,程序会花费大量时间等待I/O操作的完成。网络轮询器是golang runtime用来处理I/O操作的关键部件,它使用了操作系统提供的I/O多路复用机制增强并发能力。
设计原理
网络轮询器不仅用于监控网络I/O,还用于监控文件I/O。
I/O模型
操作系统中包含阻塞、非阻塞、信号驱动、异步以及I/O多路复用五种模型。
文件描述符(FD)是用于访问文件或者其他I/O资源的抽象句柄。不同的I/O模型会使用不同的方式操作文件描述符。
-
阻塞I/O
最常见的I/O模型,默认模式下通过系统调用读写文件时,应用程序会被阻塞。当执行read进行系统调用时,应用程序会从用户态陷入内核态,内核检查文件描述符是否可读,当文件描述符中存在数据时,内核会将数据复制给应用程序并交还控制权。
-
非阻塞I/O
当进程把文件描述符设置为非阻塞时,会立马返回,后续不断轮询知道获取返回值。
-
I/O多路复用
用来处理同一个事件循环中的多个 I/O 事件,常见的系统调用是select,可以同时监听最多1024个文件描述符的状态。
操作系统还提供poll函数,使用链表存储文件描述符。多路复用函数会阻塞监听一组文件描述符,当变为可读或者可写时,返回对应的个数,从而执行相应的操作。redis nginx也使用该模型进行I/O操作。linux epoll
Select/poll Poll FD文件句柄数 1024 不限 查询方式 轮询 回调函数,不会随着FD增加查询效率下降 使用mmap加速内核 与用户空间的消息传递
- 原文作者:nepp
- 原文链接:https://nepp-an.github.io/post/golang%E7%BD%91%E7%BB%9C%E8%BD%AE%E8%AF%A2%E5%99%A8/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。