Skip to main content

IO

五大IO模型

应用程序的进程发起IO调用,如果内核的数据还没准备好,应用程序进程就一直在阻塞等待,等到内核数据准备好后,从内核拷贝到用户空间,才返回成功提示,此次IO操作,称之为阻塞IO img.png

非阻塞IO模型

如果内核数据还没准备好,可以先返回错误信息给用户进程,让它不需要等待,而是通过轮询的方式再来请求,这就是非阻塞IO img.png

IO多路复用模型

IO多路复用之select

应用进程通过调用select函数,可以同时监控多个fd,在select函数监控的fd中,只要有任何一个数据状态准备就绪了,select函数就会返回可读状态,这时应用进程再发起recvfrom请求去读取数据 img.png select有几个缺点:

  • 最大连接数有限,在Linux系统上一般为1024。
  • select函数返回后,是通过遍历fd set,找到就绪的描述符fd。

IO多路复用之epoll

为了解决select存在的问题,多路复用模型epoll诞生,它采用事件驱动来实现 img.png epoll先通过epoll_ctl()来注册一个fd(文件描述符),一旦基于某个fd就绪时,内核会采用回调机制,迅速激活这个fd,当进程调用epoll_wait()时便得到通知。这里去掉了遍历文件描述符的坑爹操作,而是采用监听事件回调的机制。这就是epoll的亮点

信号驱动模型

信号驱动IO不再用主动询问的方式去确认数据是否就绪,而是向内核发送一个信号(调用sigaction的时候建立一个SIGIO的信号),然后应用用户进程可以去做别的事,不用阻塞。当内核数据准备好后,再通过SIGIO信号通知应用进程,数据准备好后的可读状态。应用用户进程收到信号之后,立即调用recvfrom,去读取数据 img.png

异步IO模型AIO

AIO实现了IO全流程的非阻塞,就是应用进程发出系统调用后,是立即返回的,但是立即返回的不是处理结果,而是表示提交成功类似的意思。等内核数据准备好,将数据拷贝到用户进程缓冲区,发送信号通知用户进程IO操作执行完毕。 img.png