IO 多路复用解决的啥问题

【IO 多路复用解决的啥问题】

首先抛出一个问题:C10K 问题是个什么问题?

从整个系统的服务能力来看 C10K 首先是一个关于连接,尤其是长连接的问题,只是高并发的一个前置条件,即一个进程支持大量连接的问题,接入连接之后的是否能够提供服务是另一个问题了。

IO 多路复用,解决的也就是这个前置条件,关于一个进程维持大量连接这件事儿。

对于近几年从业的小伙伴来说,不知道会不会有我一样的疑问,为什么说 BIO 的时候,就提到一个连接一个线程,他们就不会用线程池吗?

首先要分两种线程:I/O 线程 和 工作线程,对于 BIO 来说,I/O 线程同时也是工作线程,它本身的模型会阻塞住 I/O 线程,整体系统服务能力受限于线程的数量。

如果用线程池呢?当 BIO 用于短连接的时候,可以避免创建大量线程,避免系统资源耗尽,对于长连接来说,则只能服务线程池数量的连接数,一个连接一个线程说的是一个连接一个 I/O 线程。

同时,有些现在我们习以为常的东西,在那个年代是不存在的,比如我们现在随便一个进程都可以维持成千上百个连接的能力,硬件性能也上去了,就是一个连接一个线程也不是不行,但是在那个年代,抱歉,不可以,一个进程能打开的连接数量就是受限制的,硬件性能也不行,前提条件就给卡死了。

预备知识:

  • 一个 socket 连接会对应一个文件描述符 fd
  • 一个进程能打开持有的 fd 的数量是随着技术发展(历史进程)不断增加的

select 和 poll 出现之前

在 select 和 poll 出现之前,一个进程能打开的连接的数量 (fd) 是非常少的(只有几十个),也就是说一个进程只能支撑几十个连接,大量连接,就要建立大量进程,这时候可以多进程吗?是可以的,但是同时能处理的最大连接数量依旧不多,因为主要限制在一个进程就只能维持那很少的连接数(内核不允许多)。整体系统容量,连 C10K 的前提条件:大量连接,都满足不了。

另:在那个年代,有没有线程还是另外一回事儿。

select 和 poll 出现之后

select 和 poll 几乎同时出现,可以理解为一个东西的两种不同实现,具体怎么实现的,暂不表,都是内核提供的特性,我吹的再牛逼,也只是个调 API 的。

两个特点:

  1. 单进程单线程维持大量连接的能力
  2. 不阻塞 I/O 线程,意味着只要有一个 I/O 线程就可以了

select 一次最大支持 1024 个连接(默认,不建议改,改会有不可预知的行为),支持的 fd 号限制在 0~1023。

poll 则几乎没有限制连接数量。

那 select 和 poll 有什么问题呢?

  1. 用户态和内核态数据拷贝问题
  2. 每次都要遍历检查所有的 fd (遍历所有的 fd 拿到有消息的连接去处理)

当连接数量非常大的时候,它自身就会有严重的性能问题。

在这个时期,可以单进程大量连接并且不阻塞 I/O 线程,一般就是一个 I/O 线程和一组工作线程(进程)去提供服务就可以了,可以尝试解决 C10K 问题了,前置条件能够满足了。

epoll 出现

epoll 是作为 poll 的改良出现的,解决了上面说的 select 和 poll 在保持大量连接时自身的性能问题,主要改良就是不再遍历所有 fd,而是查表。

ps:当大量忙连接的时候 select 的性能表现可能比 epoll 要好。

现代程序,Linux 平台几乎都是封装了 epoll 的上层解决方案。

Python 的 tornado,Java 的 netty,还有 Nginx,Redis 等等都是在 epoll 的基础上进行的封装,但这些程序就全靠 epoll 了么?不是的,上面说了,IO 多路复用只是解决了这其中的连接的问题,后面的具体服务,还要靠大牛们的模块划分,合理抽象搞出简单好用的 API 来提供给我们用。

总结

IO 多路复用是操作系统提供用来解决单进程单线程持有大量连接和不阻塞 I/O 线程的。

不要纠结于同步,异步,阻塞,非阻塞这些名词,真想了解细节,就去看 APUE。

相对于同步还是异步,更关心,阻塞还是非阻塞,只要不阻塞,一切都好说。

按我理解这些整体都可以理解为 Selector 模型,而 select,poll,epoll 都是对于这一方案的填坑型实现。

现在最好的解决方案,应该是 epoll + 协程 的实现,一个 I/O 线程对应 n 多个协程。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lixifun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值