网络IO总结

网络IO的模式包括同步IO,异步IO,阻塞IO,非阻塞IO;这些IO模式之间的区别和联系是任何一个搞网络编程(Socket编程)的人必须弄清楚的问题,下面我们就来一层层的揭开他们的面纱吧。在Unix网络编程第一卷第六章中讨论了五种IO模型:

1. 阻塞IO(Blocking IO)

2. 非阻塞IO(Nonblocking IO)

3. IO多路复用(IO multiplexing)

4. Signal Driven IO(实际中一般不使用)

5. 异步IO(Asynchronous IO)

由于第4种在实际中一般不使用,所以接下来在本文中我们就讨论其余4种模型;在讨论模型之前,我们首先要明确IO过程中两个非常重要的步骤(所有的IO模型都是用户进程和内核在这两个步骤上交互模式不同):

1. 内核等待数据准备(内核等待协议栈中运输层接收缓冲区或发送缓冲区就绪)

2. 内核将缓冲区中的数据拷贝用户态进程的地址空间中

Blocking IO

在Linux中,默认的Socket通信模式就是阻塞IO,该模式的过程如下图所示:

从上图可以看出,当用户进程开始调用recvfrom的时候,内核就开始等待数据,当数据准备好之后,内核立即将数据从内核缓存中拷贝到进程的地址空间中,整个过程完成之后,recvfrom调用返回;在此之间,用户进程被阻塞。

Nonblocking IO

当用户希望以非阻塞的方式进行IO通信时,可以设置Socket为非阻塞,非阻塞的模式图如下:

当用户进程调用recvfrom时,假如此时内核正在等待数据,则该调用会立即返回错误;假如此时数据已经准备好了,则内核会立即将数据拷贝到用户进程的地址空间中并成功返回;上面图示的是应用进程在不断的轮询,直到内核中数据准备好并成功返回为止。

IO multiplexing

IO多路复用也被称为事件驱动IO(Event Driven IO),我们常用的select, poll, epoll等系统调用就是这种模型;这种模型的优点是可以同时处理多个socket连接。其基本原理是select/epoll系统调用会不断轮询所负责的所有socket连接,一旦某个socket的数据已经准备好,select便立即返回;然后用户进程调用recvfrom触发内核将该socket对应的数据从内核空间拷贝到应用进程的地址空间中并成功返回。

在IO multiplexing Model中,socket一般都被设置成non-blocking,但是,如上图所示,内核在等待数据就绪的时候,用户进程其实是block的,只不过进程是被select这个函数block,而不是被socket IO给block。

该模型用于服务器中对多个网络并发连接进行处理会非常有效,分布式缓存Memcached的服务端及常用的Web服务器就采用这种模型,Libevent就是基于这个模型实现的库。

异步IO

Linux中异步IO其实用的非常少,它的模型如下图所示:

从图中我们可以看出,当用户进程发起IO请求时,如果内核数据没有准备好,则会立刻返回;返回后用户进程继续做之后的事情,而内核则等待数据就绪并将数据从内核拷贝到用户空间,同时发送aio_read中指定的信号给用户进程,告诉它数据已经成功发送给它。

下面我们来看看阻塞和非阻塞、同步和异步的内涵及区别:

阻塞、非阻塞是指当调用一个函数时,他是否能够立即返回;

同步、异步是指进程间通信是否经过协调,是进程间通信的模型;比如进程A需要等待进程B执行完某件事情之后才能继续执行,这就是同步;假如进程A的执行和进程B的执行好不相干,这就是异步;

因此,我们可以说阻塞调用或非阻塞调用,但不能说同步调用及异步调用,只能说同步通信或异步通信

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值