网络编程 I/O复用(1)

1.什么是IO复用

在《unix网络编程》一书中是这样说的:一种能预先告知内核的能力,使得内核一旦发现进程指定的一个或者多个I/O条件 就绪(也就是输入已经准备好被读取,或者描述符已能承接更多的输出)它就通知进程,这种能力就叫I/O复用。

2.什么时候使用IO复用(网络应用场合)

1)当客户端处理多个描述符(通常是交互式输入和网络套接字),都会发生阻塞,就必须使用I/O复用。

2)如果一个tcp既要处理监听套接字,又要处理已经连接的套接字,一般要用到I/O复用

3)如果一个服务器既要tcp,又要处理udp,一般就要使用I/O复用

4)如果服务器要处理多个服务或者多个协议一般要用到I/O复用

3.I/O复用的模型

在说I/O复用之前,有必要说说I/O模型

在unix下有5中I/O模型 A、阻塞式I/O,B、非阻塞I/O,C、I/O复用(select和epoll等), D 、信号驱动式I/O,F、异步I/O。

阻塞式I/O

在默认情况下所有的套接字都是阻塞的 拿udp通信作为例子 阻塞式I/O 可以由下图表示,在等待数据的过程中系统会将本进程投入睡眠状态,直到返回成功标识。

164542_HUei_2865380.png

借用前辈的例子理解阻塞式I/O:就好比我们在京东或者淘宝买了一件宝贝(网络中传递的消息),这件宝贝还在商家(网络的对端)这里,商家会将宝贝交给快递小哥(网络中传递的消息传到了本地内核buf),这时你想要知道宝贝到那个地方了,到底发货了,到了快递员手中(消息到了系统底层的buf中)还是没有,于是你调用了一个方法(recvfrom):打电话给快递小哥,问他货物到他那里了没有,如果你得到的结果是:宝贝已经到你楼下,那自然你就取宝贝了。但是如果快递小哥说还没有宝贝,还得再等等,于是你就跑去睡觉了(进程进入了睡眠状态),因为你知道如果宝贝到了的话快递小哥会给你电话(返回成功指示),这时候你再起床去取件。

非阻塞I/O

把套接字设置为非阻塞是为了通知内核,进程调用recvfrom时,如果没有准备好数据不要将本进程投入到睡眠状态,而是返回一个错误标识。而我们要做的便是:对一个非阻塞描述符不断调用recvfrom,去查看是否有数据准备好,我们把这种方式称为轮询。

174804_Bn3p_2865380.png

应用程序不断轮询内核,查看数据是否准备好,势必会耗费大量的cpu时间。因此会有下面的I/O复用

套用刚才的例子:就好比你不知道宝贝到哪了,于是你隔几秒就打电话给快递小哥,询问宝贝的运输状态。势必会占用了快递小哥的时间,但是对于内核会义不容辞地每次都和说,亲,数据还没准备好哟,要是换做在现实生活,快递小哥都想抽你是吧!

I/O复用

有了I/O复用,可以调用select和epoll等后端(后端这种叫法在libevent中出现)阻塞在这些后端调用之上,而不是真的在IO上发生阻塞。

180352_5ZeA_2865380.png

对于后两者:D 、信号驱动式I/O,F、异步I/O,暂时了解不是很深!这里不做记录。

至于这个举个例子的话,我觉得I/O复用这些机制就好比像 "中集e站" 一样,从不同商家买的东西, 通过不同快递员,最后货品都会放到中集e站中去,由中集e站统一通知你,让你去中集e站取快件!

在不同的系统支持的I/O复用模式有差异,平常用的是linux系统,因此对select和epoll这两种I /O复用模型涉及比较多,而关于这两种复用模型的使用在下篇文章中记录。

转载于:https://my.oschina.net/yaomianwei/blog/732486

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值