网络轮询器

大部分服务都是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加速内核 与用户空间的消息传递

    http://blog.chinaunix.net/uid-28541347-id-4232252.html