分享

五种IO模式简介

 猎狐肥 2020-05-28

对于一次IO访问(以read举例),数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的内存地址空间。所以说,当一个read操作发生时,它会经历两个阶段:
1. 等待内核缓冲区中数据准备 (Waiting for the data to be ready)
2. 将数据从内核缓冲区拷贝到进程中 (Copying the data from the kernel to the process)

正式因为这两个阶段,linux系统产生了下面五种IO模式的方案:

  1. 阻塞 I/O(blocking IO)
  2. 非阻塞 I/O(nonblocking IO)
  3. I/O 多路复用( IO multiplexing)
  4. 异步 I/O(asynchronous IO)
  5. 信号驱动 I/O( signal driven IO)

阻塞I/O(blocking IO)

当一个进程需要read数据时,它需要先从内核缓存区中读取数据,当在内核中数据还未准备好时,则该进程会被阻塞(block),直到数据准备好为止。

非阻塞 I/O(nonblocking IO)

一个进程需要read数据时,它需要先从内核缓存区中读取数据,当在内核中数据还未准备好时,内核立即返回error,用户进程得知error后,会继续read,直到数据准备好为止。

I/O 多路复用( IO multiplexing)

上述阻塞IO和非阻塞IO,当时一个用户进程对应一个IO操作,IO多路复用则通过一定的机制实现了一个进程可以对应多个IO操作。

IO多路复用主要有select、poll、epoll三种模式,select/poll相差不大,主要是通过轮询来不断的检测是否有描述符已就绪,select默认情况下支持最多监控1024个描述符,poll则没有这个限制(底层通过链表实现,可动态增加);epoll不是通过轮询,而是通过回调(callback)方式主动通知已有描述符已就绪,相比较select/poll效率有明显提升。

不管哪种模式的IO多路复用,还都是同步IO,比如当监控的所有的描述符都还没有准备就绪,那么该进程还是阻塞在此,下面将介绍异步IO

异步 I/O(asynchronous IO)

相比较同步IO,异步IO就显得更加高大上了,基本原理是用户进程发起read操作之后,立刻就可以开始去做其它的事。而另一方面,从kernel的角度,当它受到一个asynchronous read之后,首先它会立刻返回,所以不会对用户进程产生任何block。然后kernel会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel会给用户进程发送一个signal,告诉它read操作完成了,用户进程收到signal后获取已准备好的数据。

信号驱动 I/O( signal driven IO)

信号驱动IO和异步IO类似,甚至有些人认为信号驱动IO就是异步IO,当kernel准备好数据后,会发送signal给用户进程,告诉进程数据已经准备就绪,这时进程会主动去read数据将数据拷贝到用户内存,这一步是由应用程序自己操作的,而异步IO则是由kernal实现,区别在此。

 

nginx在IO多路复用模式有较成熟的应用;

python在异步IO模式上也有相应的应用,例如gevent、asyncio等。

 

参考资料:https://www.cnblogs.com/mao3714/p/8184262.html

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多