网络通信模型(IO模型)学习摘要

Posted 狠一点

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络通信模型(IO模型)学习摘要相关的知识,希望对你有一定的参考价值。

1、概念

《Unix网络编程:卷1》中介绍了5种I/O模型,JAVA作为运行在宿主机上的程序,底层也遵循这些规则。

  • 阻塞式IO(Blocking IO):即传统的IO模型;

  • 非阻塞式IO(Non-blocking IO):默认创建的socket都是阻塞的,非阻塞IO要求socket被设置为NONBLOCK,注意这里所说的NIO并非Java的NIO(New IO)库;

  • IO多路复用(IO Multiplexing):即经典的Reactor设计模式,Java中的Selector和Linux中的epoll都是这种模型;

  • 信号驱动式IO:

  • 异步IO:即经典的Proactor设计模式,也称为异步非阻塞IO;

按POSIX标准来分,IO分为同步和异步,上面的前4种都属于同步IO。

一个IO分为两个阶段:

  1. 等待数据:数据可能来自其他应用程序或者网络,如果没有数据,操作系统就一直等待,应用程序就跟着等待;

  2. 拷贝数据:将就绪的数据拷贝到应用程序工作区;

在Unix系统中,操作系统的IO操作是一个系统调用recvfrom(),即一个系统调用recvfrom包含两步,等待数据就绪和拷贝数据。

同步和异步:描述的是用户线程与内核的交互方式。同步是指用户线程发起IO请求后需要等待或者轮询内核IO操作完成后才能继续执行。而异步是指用户线程发起IO请求后仍继续执行,当内核IO操作完成后会通知用户线程,或者调用用户线程注册的回调函数。

阻塞和非阻塞:描述的是用户线程调用内核IO操作的方式。阻塞是指IO操作需要彻底完成后才返回到用户空间。而非阻塞是指IO操作被调用后立即返回给用户一个状态值,无需等到IO操作彻底完成。

2、IO模型

2.1、blocking I/O

application调用 recvfrom()转入kernel,直到最后copy complete后,recvfrom()才返回,此过程一直是阻塞的。

2.2、nonblocking I/O

网络通信模型(IO模型)学习摘要

不断轮询直到内核缓冲区有数据,由于轮询会消耗大量CPU时间,这种模式并不常用。

阻塞IO与非阻塞IO的关键区别在于,系统调用recvfrom是否立即返回。

 2.3、I/O multiplexing (select/poll/epoll) 

网络通信模型(IO模型)学习摘要

最常见的I/O复用模型,与blocking I/O相比,select会有两次系统调用,但是select能处理多个套接字,服务器只需要一两个线程就可以进行多客户端通信。

2.4、signal driven I/O (SIGIO) 

网络通信模型(IO模型)学习摘要

只有UNIX系统支持,与I/O multiplexing相比,它的优势是,免去了select的阻塞与轮询,当有活跃套接字时,由注册的handler处理。

2.5、asynchronous I/O

很少有*nix系统支持,windows的IOCP则是此模型,完全异步的I/O复用机制,纵观上面其它四种模型,至少都会在由kernel copy data to appliction时阻塞。而该模型是当copy完成后才通知application,可见是纯异步的。好像只有windows的完成端口是这个模型,效率也很出色。

2.6、五种模型的比较 

可以看出,越往后,阻塞越少,理论上效率也是最优。

3、select、poll、epoll的区别

select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。selectpollepoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。

select缺点:

a、每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大;

b、同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大;

c、select支持的文件描述符数量太小了,默认是1024;

poll

poll的实现和select非常相似,只是描述fd集合的方式不同,poll使用pollfd结构而不是select的fd_set结构,其他的都差不多。 

epoll

select和poll的增强版本

a、 每次注册新的事件到epoll句柄中时都会拷贝进内核,保证了每个fd在整个过程中只会拷贝一次;

b、 为每个fd指定一个回调函数,当设备就绪,唤醒等待队列上的等待者时,就会调用这个回调函数,而这个回调函数会把就绪的fd加入一个就绪链表,只需在就绪链表中查看有没有就绪的fd;

c、 epoll没有这个限制,它所支持的FD上限是最大可以打开文件的数目;

 

以上是关于网络通信模型(IO模型)学习摘要的主要内容,如果未能解决你的问题,请参考以下文章

python学习四十三天(网络IO模型)

OSI七层模型 学习摘要

五种 IO 模型

Java网络编程和NIO详解3:IO模型与Java网络编程模型

第95p,最常见的4种网络IO模型

UNIX网络编程——网络I/O模型