在这个过程中,最最最关键点在于其中的一行代码:在这里调用了 poll 方法,执行具体的事件拉取逻辑,进一步往下走:最后会调用 WindowsSelectorImpl.poll 方法,而该方法最终会调用本地的 native 方法: poll0 方法,而在 JVM 的源码实现中,该方法最终会调用内核所提供的函数。
多路复用的适用场合• 当客户处理多个描述符时(例如同时处理交互式输入和网络套接口) • 如果一个TCP服务器既要处理监听套接口,又要处理已连接套接口 • 如果一个服务器即要处理TCP,又要处理UDP • 如果一个服务器要处理多个服务或多个协议 select/poll/epoll差
所有的网络相关的动作都是在一个进程里完成的,如监听 socket 的创建, bind、listen。事实上,Redis 5.0 及以前的版本中,它的网络部分去掉对 handler 的封装,去掉时间事件以后,代码基本和上述 demo 非常接近。
通过 sendfile 系统调用,数据可以直接在内核空间内部进行 I/O 传输,从而省去了数据在用户空间和内核空间之间的来回拷贝,sendfile 调用中 I/O 数据对用户空间是完全不可见的,整个拷贝过程会发生 2 次上下文切换,1 次 CPU 拷贝和 2 次 DMA 拷贝。