资料
Linux IO模式及select、poll、epoll详解
系统调用、用户空间、内核空间
为了保证操作系统的安全,将内存划分为内核空间和用户空间。内核空间的进程,可以访问硬件执行IO等操作,用户空间的进程只能通过系统调用来访问IO等系统资源。
IO模型的区分依据
对于一次IO访问(以read举例),数据会先被拷贝到操作系统内核的缓冲区中,然后再拷贝到应用程序的地址空间。
所以,当一个read操作发生时,它会经历两个阶段
- 等待数据准备(Waiting for the data to be ready)
- 将数据从内核拷贝到进程中(Copying the data from the kernel to the process)
正是因为这两个阶段,linux系统产生了下面五种网络模型:
- 阻塞IO
- 非阻塞IO
- IO多路复用
- 信号驱动IO
- 异步 IO
阻塞IO
在linux下,默认情况下所有的socket都是blocking的,流程如下图所示:
阻塞IO流程图.png
进程调用recvfrom系统调用来读取数据,这是如果还没有到达,进程就进入阻塞状态。等数据到达后完成到内核去的拷贝,再从内核拷贝到用户空间,用户进程才解除阻塞状态。
特点:在IO执行的两个阶段进程都会都阻塞
非阻塞IO
非阻塞IO流程图.png执行非阻塞io系统调用时,如果内核中的数据还没有准备好,会直接返回,不会阻塞。通过进程不断查询,直到数据在内核中就绪,便开始拷贝到用户空间。拷贝的过程中,进程还是被阻塞了,所有非阻塞IO也是同步IO。
特点:需要进程不断地主动询问kernel数据是否准备好了
IO多路复用
IO多路复用流程-以select为例.png单个进程处理多个网络连接IO,使用select\poll\epoll三种系统调用,不断轮询所有的连接,如果有数据到达内核则通知进程,进行数据拷贝到用户内存。
当调用select时,进程会进入阻塞状态,直到有数据到达。
这个图看起来和阻塞IO区别不大,甚至还多使用了一个系统调用
但它的优势在于可以同时监控多个IO连接。
所以,如果连接数不是很高的话,使用select/epoll的web server不一定比使用multi-threading + blocking IO的web servet性能更好。多路IO复用的优势并不是对于单个连接能处理的更快,而在于能处理更多的连接。
异步IO
linux下的异步io使用的很少,其流程如下:
异步IO流程图.png
发起read操作后进程立马返回,整个Io过程不会产生任何block。kernel会等等数据准备完成,然后将数据拷贝到用户内存。当这一切都完成后,kernel会给用户进程发送一个signal,告诉它read操作完成了。
阻塞IO和非阻塞IO的区别
调用blocking io会一直block进程直到操作完成
no-blocking io在kernel准备数据的阶段是会立刻返回的
同步和异步的区别
只有异步IO是异步IO,
其他3种:阻塞IO、非阻塞IO、多路复用IO都是同步的。
这是因为其他三种IO在执行真实IO操作的过程中都有进程阻塞的阶段,而异步IO在整个过程中进程都没有被阻塞。非阻塞IO在内核数据就绪,拷贝到用户空间的阶段也是阻塞的,因此也是同步IO。
网友评论