在 Redis 中,我们通过宏定义的使用,合理的选择不同的子模块:
#ifdef HAVE_EVPORT #include "ae_evport.c" #else#ifdef HAVE_EPOLL#include "ae_epoll.c"#else#ifdef HAVE_KQUEUE#include "ae_kqueue.c"#else#include "ae_select.c"#endif#endif #endif 因为 select 函数是作为 POSIX 标准中的系统调用,在不同版本的操作系统上都会实现,所以将其作为保底方案:
文章插图
Redis 会优先选择时间复杂度为 $O(1)$ 的 I/O 多路复用函数作为底层实现,包括 Solaries 10 中的 evport、linux 中的 epoll 和 macOS/FreeBSD 中的 kqueue 。
上述的这些函数都使用了内核内部的结构,并且能够服务几十万的文件描述符 。
但是如果当前编译环境没有上述函数,就会选择 select 作为备选方案,由于其在使用时会扫描全部监听的描述符,所以其时间复杂度较差 O(n) 。
并且只能同时服务 1024 个文件描述符,所以一般并不会以 select 作为第一方案使用 。
总结
Redis 对于 I/O 多路复用模块的设计非常简洁,通过宏保证了 I/O 多路复用模块在不同平台上都有着优异的性能,将不同的 I/O 多路复用函数封装成相同的 API 提供给上层使用 。
整个模块使 Redis 能以单进程运行的同时服务成千上万个文件描述符,避免了由于多进程应用的引入导致代码实现复杂度的提升,减少了出错的可能性 。
作者:Draveness来源:Draveness|
【为什么单线程的Redis却能支撑高并发?】
推荐阅读
- 简单又实用的台湾日月潭红茶冲泡方法
- 实现扫码登陆的最简单方案与原理
- 台湾日月潭红茶的冲泡方法 简单又实用
- 伞竹怎么养才能长的有粗又高的简单介绍
- 茶化石那些传闻 为什么不建议喝碎银子?
- 永远不要在春节的时候相亲 大龄单身过年该不该相亲
- 一亿像素影像横评 hm2是什么单位
- 为什么现在的男生都喜欢姐姐,为什么现在的00后喜欢姐弟恋
- 如何选购坦洋工夫红茶坦洋工夫为什么这么火
- 事业单位的薪级工资是怎么计算的?