java-IO-多路复用机制

  • 文件描述符(file descriptor)
  1. Linux中,每打开一个文件都有一个小的整数与之对应,就是文件描述符!
  2. 内核(kernel)利用文件描述符(file descriptor)来访问文件。文件描述符是非负整数。打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。
  3. 文件描述符是linux里面的叫法,windows里面有类似用来描述文件的叫文件句柄
  • 用户空间 / 内核空间
  1. 操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。
  2. 为了保证用户进程不能直接操作内核(kernel),保证内核的安全,操作系统将虚拟空间划分为两部分,一部分为内核空间,一部分为用户空间。
  • 缓存I/O
  1. 在Linux的缓存I/O机制中,操作系统会将I/O的数据缓存在文件系统的页缓存中
  2. 即数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。
  • I/O多路复用(multiplexing)
  1. 本质:通过一种机制(系统内核缓冲I/O数据),让单个进程可以监视多个文件描述符,一旦某个描述符就绪(一般是读就绪或写就绪),能够通知程序进行相应的读写操作
  2. 优势:系统开销小,系统不必创建进程/线程,也不必维护这些进程/线程,从而大大减小了系统的开销。
  • select机制
  1. 基本原理:select 函数监视的文件描述符分3类,分别是writefds、readfds、和exceptfds。调用后select函数会阻塞,直到有描述符就绪(有数据 可读、可写、或者有except),或者超时(timeout指定等待时间,如果立即返回设为null即可),函数返回。当select函数返回后,可以通过遍历fdset,来找到就绪的描述符。
  2. 缺点:每次调用select,都需要把fd_set集合从用户态拷贝到内核态,如果fd_set集合很大时,那这个开销也很大;同时每次调用select都需要在内核遍历传递进来的所有fd_set,如果fd_set集合很大时,那这个开销也很大;为了减少数据拷贝带来的性能损坏,内核对被监控的fd_set集合大小做了限制,并且这个是通过宏控制的,大小不可改变(限制为1024)
  • poll机制
  1. poll的机制与select类似,管理多个描述符也是进行轮询,根据描述符的状态进行处理
  2. 但是poll没有最大文件描述符数量的限制,poll改变了文件描述符集合的描述方式,使用了pollfd结构而不是select的fd_set结构,使得poll支持的文件描述符集合限制远大于select的1024
  • epoll机制
  1. 基本原理:epoll支持水平触发和边缘触发,最大的特点在于边缘触发,它只告诉进程哪些fd刚刚变为就绪态,并且只会通知一次。还有一个特点是,epoll使用“事件”的就绪通知方式,通过epoll_ctl注册fd,一旦该fd就绪,内核就会采用类似callback的回调机制来激活该fd,epoll_wait便可以收到通知。
  2. 优点:1、epoll没有描述符个数限制,使用一个文件描述符管理多个描述符,将用户关心的文件描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间的copy只需一次。2、是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率,原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。
  • 总结

参考:

  1. IO多路复用的三种机制Select,Poll,Epoll    https://www.jianshu.com/p/397449cadc9a 
  2. IO多路复用技术详解    https://www.cnblogs.com/wlwl/p/10293057.html
  3. Redis IO多路复用技术以及epoll实现原理    https://blog.csdn.net/wxy941011/article/details/80274233

猜你喜欢

转载自blog.csdn.net/m0_37524661/article/details/87916779