各种IOAndroid知识Android开发经验谈

细谈Select,Poll,Epoll

2017-07-31  本文已影响626人  六尺帐篷
  • 阻塞 io 模型 blocking IO
  • 非阻塞 io 模型 nonblocking IO
  • io多路复用模型 IO multiplexing
  • 细谈 io 多路复用技术 select 和poll
  • 细谈事件驱动--epoll
  • 总结

操作系统在处理io的时候,主要有两个阶段:

我们一般将上述过程简化理解为:

而根据这两个阶段而不同的操作方法,就会产生多种io模型,本文只讨论select,poll,epoll,所以只引出三种io模型。

阻塞 io 模型 blocking IO

最常用的也就是阻塞io模型。默认情况下,所有文件操作都是阻塞的。我们以套接字接口为例来讲解此模型,在进程空间调用recvfrom,其系统调用知道数据包到达并且被复制到进程缓冲中或者发生错误时才会返回,在此期间会一直阻塞,所以进程在调用recvfrom开始到它返回的整段时间都是阻塞的,因此称之为阻塞io模型。

注意:在阻塞狀態下,程序是不會浪費CPU的,cpu只是不执行io操作了,还会去做别的。

image.png

应用层有数据过来,会调用recvfrom方法,但是这个时候应用层的数据还没复制到kernel中,将应用层数据复制到kerne这个阶段是需要时间的,所以recvfrom方法会阻塞,当内核中的数据准备好之后,recvfrom方法还不会返回,而是会发起一个系统调用将kernel中的数据复制到进程的缓冲区中,也就是user space,当这个工作完成之后,recvfrom才会返回并解除程序的阻塞。

所以我们总结可以发现,主要就是上面两个阶段

阻塞io模型就是将这个两个过程合并在一起,一起阻塞。
而非阻塞模型则是将第一个过程的阻塞变成非阻塞,第二个阶段是系统调用,是必须阻塞的,所以非阻塞模型也是同步的,因为它们在kernel里的数据准备好之后,进行系统调用,将数据拷贝到进程缓冲区中。

非阻塞 io 模型 nonblocking IO

就是对于第一个阶段,也就是应用层数据到kernel的过程中,recvfrom会轮询检查,如果kernel数据没有准备还,就返回一个EWOULDBLOCK错误。不断的轮询检查,直到发现kernel中的数据准备好了,就返回,然后进行系统调用,将数据从kernel拷贝到进程缓冲区中。有點類似busy-waiting的方法。

image.png

io多路复用模型 IO multiplexing

image.png

细谈 io 多路复用技术 select 和poll

select

select的工作流程:
单个进程就可以同时处理多个网络连接的io请求(同时阻塞多个io操作)。基本原理就是程序呼叫select,然后整个程序就阻塞了,这时候,kernel就会轮询检查所有select负责的fd,当找到一个client中的数据准备好了,select就会返回,这个时候程序就会系统调用,将数据从kernel复制到进程缓冲区。

image.png

下图为select同时从多个客户端接受数据的过程

虽然服务器进程会被select阻塞,但是select会利用内核不断轮询监听其他客户端的io操作是否完成。

image.png

Poll介绍

poll的原理与select非常相似,差别如下:

select缺点

1.每一次呼叫 select( ) 都需要先从 user space把 FD_SET复制到 kernel(约线性时间成本)
为什么 select 不能像epoll一样,只做一次复制就好呢?
每一次呼叫 select()前,FD_SET都可能更动,而 epoll 提供了共享记忆存储结构,所以不需要有 kernel 與 user之间的数据沟通

2.然后kernel还要轮询每个fd,约线性时间

对于select和poll的上述缺点,就引进了一种新的技术,epoll技术

细谈事件驱动--epoll

epoll 提供了三个函数:

epoll解决的问题:

总结

上一篇 下一篇

猜你喜欢

热点阅读