网络IO模型(同步异步,阻塞非阻塞)

来源:互联网 发布:java富有创意的小程序 编辑:程序博客网 时间:2024/05/22 13:43


摘录自:http://www.jianshu.com/p/55eb83d60ab1#


网络应用需要处理的无非两大类问题:网络I/O,数据计算

网络IO的模型大致有如下几种:

 

同步模型:

         阻塞

         非阻塞

         多路复用

         信号驱动式

异步IO

 

网络IO的本质是socket的读取,socket在linux系统被抽象为流,IO可以理解为对流的操作。

这个操作分为2个阶段:

1 等待流数据准备

2 从内核向进程复制数据

 

对于socket流而言,

第一步通常涉及等待网络上的数据分组到达,然后被复制到内核的某个缓冲区

第二步把数据从内核缓冲区复制到应用进程缓冲区

 

1      阻塞IO

阻塞,就是进程被休息,cpu处理其他进程去了。在网络IO的时候,进程发起recvform系统调用,然后进程就被阻塞了,什么也不干,直到数据准备好,并且将数据从内核复制到用户进程。最后进程再处理数据,在等待数据和处理数据这两个阶段,整个进程都被阻塞。不能处理别的网络IO

 

2      非阻塞IO

与阻塞IO不一样,非阻塞IO在recvform系统调用之后,进程并没有阻塞,内核会马上返回给进程,如果数据还没准备好,此时会返回一个erro。进程在得到这个返回后,可以干别的事情。然后再发起recvform系统调用。重复上面的过程,循环往复的进行recvform系统调用。这个过程称为轮询。轮询检查内核数据,直到数据准备好,再拷贝数据到进程,进行数据处理。拷贝数据的整个过程,进程仍然是阻塞态的

         非阻塞IO的特点是用户进程需要不断的主动询问kernel数据是否准备好

3      多路复用IO

由于非阻塞的调用,轮询占据了很大一部分过程,会消耗大量的cpu时间。

如果轮询不是进程的用户态,而是有人帮忙就好了。这就是多路复用。

多路复用有2个特别的系统调用select或poll。

Select调用时内核级别的,select轮询相对非阻塞的轮询在于—前者可以等待多个socket,当其中任何一个socket的数据准备好,就能返回进行可读。

多路复用有两种阻塞,select或poll调用之后,会阻塞进程,与第一种阻塞不同,此时的select不是等到socket数据全部到达再处理,而是有了一部分数据就会调用用户进程来处理。

 

多路复用的特点是 通过一种机制一个进程能同时等待IO文件描述符,内核监视这些文件描述符(套接字描述符),其中任意一个进入读就绪状态,select,poll,epoll函数就返回。

 

上述三种模式,在用户进程进行系统调用的时候,在等待数据到来时,处理方式分别是,直接等待,轮询,selectpoll轮询。从整个IO过程来看,他们都是顺序执行的,因此可以归为同步模型。都是进程主动向内核检查。

4      异步IO

相对于同步IO,异步IO不是顺序执行。用户进程进行aio_read调用之后,无论内核数据是否准备好,都会直接返回给用户进程,然后用户态进程可以去做别的事情。等到socket数据准备好,内核直接复制数据给进程,然后从内核向进程发送通知。IO两个阶段,进程都是非阻塞的。

5      区别

同步和异步,阻塞非阻塞,是两组概念。

所谓同步就是在整个IO过程,尤其是拷贝数据的过程是阻塞进程的,并且都是应用进程去检查内核态。异步则是整个IO过程,用户进程都是非阻塞的,并且数据拷贝完成后,是内核发送通知给用户进程。

 

 

 

0 0