可以从 Go 源码目录结构和对应代码文件了解 Go 在不同平台下的网络 I/O 模式的实现。比如,在 Linux 系统下基于 epoll
,freeBSD 系统下基于 kqueue
,以及 Windows 系统下基于 iocp
。
由于代码运行环境主要是Linux,所以我们主要讲epoll
。
所谓 I/O 多路复用指的就是 select/epoll 这一系列的多路选择器:支持单一线程同时监听多个文件描述符(I/O 事件),阻塞等待,并在其中某个文件描述符可读写时收到通知。
int select(int nfds,
fd_set *restrict readfds,
fd_set *restrict writefds,
fd_set *restrict errorfds,
struct timeval *restrict timeout);
readfds
、writefds
、和errorfds
是三个文件描述符集合。select会遍历每个集合的前nfds个描述符,分别找到可以读取、可以写入、发生错误的描述符,统称为就绪的描述符。
timeout
表示调用select
的阻塞时长,如果所有文件描述符都未就绪,就阻塞调用进程,直到某个描述符就绪,或者阻塞超过设置的timeout后,返回。如果timeout
参数为null
,会无限阻塞直到某个描述符就行;如果为0会立即返回,不阻塞。
FD_SETSIZE
**设置,默认值是1024;epoll是select的增强版本,避免了“性能开销大”和“文件描述符数量少”的两个缺点。