作者:知乎用户
链接:https://www.zhihu.com/question/28594409/answer/52763082
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

题主是看redis相关书籍碰到了困惑,那就结合redis源码来回答题主这个问题。
redis源码地址:antirez/redis · GitHub

关于I/O多路复用(又被称为“事件驱动”),首先要理解的是,操作系统为你提供了一个功能,当你的某个socket可读或者可写的时候,它可以给你一个通知。这样当配合非阻塞的socket使用时,只有当系统通知我哪个描述符可读了,我才去执行read操作,可以保证每次read都能读到有效数据而不做纯返回-1和EAGAIN的无用功。写操作类似。操作系统的这个功能通过select/poll/epoll/kqueue之类的系统调用函数来使用,这些函数都可以同时监视多个描述符的读写就绪状况,这样,多个描述符的I/O操作都能在一个线程内并发交替地顺序完成,这就叫I/O多路复用,这里的“复用”指的是复用同一个线程。

以select和tcp socket为例,所谓可读事件,具体的说是指以下事件:
1 socket内核接收缓冲区中的可用字节数大于或等于其低水位SO_RCVLOWAT;
2 socket通信的对方关闭了连接,这个时候在缓冲区里有个文件结束符EOF,此时读操作将返回0;
3 监听socket的backlog队列有已经完成三次握手的连接请求,可以调用accept;
4 socket上有未处理的错误,此时可以用getsockopt来读取和清除该错误。

所谓可写事件,则是指:
1 socket的内核发送缓冲区的可用字节数大于或等于其低水位SO_SNDLOWAIT;
2 socket的写端被关闭,继续写会收到SIGPIPE信号;
3 非阻塞模式下,connect返回之后,发起连接成功或失败;
4 socket上有未处理的错误,此时可以用getsockopt来读取和清除该错误。

Linux环境下,Redis数据库服务器大部分时间以单进程单线程模式运行(执行持久化BGSAVE任务时会开启子进程),网络部分属于Reactor模式,同步非阻塞模型,即非阻塞的socket文件描述符号加上监控这些描述符的I/O多路复用机制(在Linux下可以使用select/poll/epoll)。服务器运行时主要关注两大类型事件:文件事件和时间事件。文件事件指的是socket文件描述符的读写就绪情况,时间事件分为一次性定时器和周期性定时器。相比nginx和haproxy内置的高精度高性能定时器,redis的定时器机制并不那么先进复杂,它只用了一个链表来管理时间事件,而且目前链表也没有对各个事件的到点时间进行排序,也就是说,每次都要遍历链表检查每个事件是否需要到点执行。个人猜想是因为redis目前并没有太多的定时事件需要管理,redis以数据库服务器角色运行时,定时任务回调函数只有位于redis/src/redis.c下的serverCron函数,所有的定时任务都在这个函数下执行,也就是说,链表里面其实目前就一个节点元素,所以目前也无需实现高性能定时器。

Redis网络事件驱动模型代码:redis/src/目录下的ae.c, ae.h, ae_epoll.c, ae_evport.c, ae_select.c, ae_kqueue.c , ae_evport.c。其中ae.c/ae.h:头文件里定义了描述文件事件和事件时间的结构体, 即aeFileEvent和aeTimeEvent;事件驱动状态结构体aeEventLoop, 这个结构体只有一个名为eventloop的全局变量在整个服务器进程中;事件就绪回调函数指针aeFileProc和aeTimeProc;以及操作事件驱动模型的各种API(aeCreateEventLoop以及之后全部的函数声明)。ae_epoll.c, ae_select.c, ae_keque.c和ae_evport.c封装了select/epoll/kqueue等系统调用,Linux下当然不支持kqueue和evport。至于究竟选择哪一种I/O多路复用技术,在ae.c里有预处理控制,也就是说,这些源文件只有一个能最后被编译。优先选择epoll或者kqueue(FREEBSD和Mac OSX可用),其次是select。

I/O多路复用技术(multiplexing)是什么?的更多相关文章

  1. Lind.DDD.RedisClient~对StackExchange.Redis调用者的封装及多路复用技术

    回到目录 两雄争霸 使用StackExchange.Redis的原因是因为它开源,免费,而对于商业化的ServiceStack.Redis,它将一步步被前者取代,开源将是一种趋势,商业化也值得被我们尊 ...

  2. 【计算机网络基础】数据交换技术和多路复用技术的正(nao)确(can)打开方式

    交换的作用   数据交换是计算机网络中两个终端进行数据传输的方式,它又可以分成两种类型:电路交换和分组交换.很显然,问题的核心在于“交换”,那么我们首先要思考的是:交换的作用是什么?   “交换”的作 ...

  3. 【计算机网络】数据交换技术和多路复用技术的正(nao)确(can)打开方式

    交换的作用   数据交换是计算机网络中两个终端进行数据传输的方式,它又可以分成两种类型:电路交换和分组交换.很显然,问题的核心在于“交换”,那么我们首先要思考的是:交换的作用是什么?   “交换”的作 ...

  4. Oracle体系结构之控制文件的多路复用技术

    在Windows操作系统中,如果注册表文件被损坏了,就会影响操作系统的稳定性.严重的话,会导致操作系统无法正常启动.而控制文件对于Oracle数据库来说,其作用就好象是注册表一样的重要.如果控制文件出 ...

  5. 解读I/O多路复用技术

    前言 当我们要编写一个echo服务器程序的时候,需要对用户从标准输入键入的交互命令做出响应.在这种情况下,服务器必须响应两个相互独立的I/O事件:1)网络客户端发起网络连接请求,2)用户在键盘上键入命 ...

  6. Redis I/O 多路复用技术原理

    引言 Redis 是一个单线程却性能非常好的内存数据库, 主要用来作为缓存系统. Redis 采用网络 I/O 多路复用技术来保证在多个连接时,系统的高吞吐量(TPS). 系统吞吐量(TPS)指的是系 ...

  7. IO多路复用技术总结

    来源:微信公众号「编程学习基地」 IO 多路复用概述 I/O 多路复用技术是为了解决进程或线程阻塞到某个 I/O 系统调用而出现的技术,使进程不阻塞于某个特定的 I/O 系统调用. 在IO多路复用技术 ...

  8. 【Http】队头阻塞(Head of line blocking)多路复用(Multiplexing)

        图中第一种请求方式,就是单次发送request请求,收到response后再进行下一次请求,显示是很低效的. 于是http1.1提出了管线化(pipelining)技术,就是如图中第二中请求方 ...

  9. IO多路复用(IO Multiplexing)

    什么是IO多路复用 为什么要有IO多路复用 作者总结 遵循学习新知识的三部曲:是什么?为什么?怎么用? 作者前言:IO多路复用本质上是网络通信过程中的一个技术名词. 什么是IO多路复用 一个用机场管理 ...

随机推荐

  1. AngularJS体验式编程系列文章

    AngularJS体验式编程系列文章,将介绍如何用angularjs构建一个强大的web前端系统.angularjs是由Google团队开发的一款非常优秀web前端框架.在当前如此多的web框架下,a ...

  2. 二次开发第N天。。。。。。。。自动分页问题

    phpcms\modules\content\fields\pages\form.inc.php 注意修改时,如果是gbk版本可以直接用记事本修改保存!如果是utf8 要用工具修改,或者保存的时候要记 ...

  3. mongodb数据库shell

    mongoexport -d mofangdb -c log_user_access_index --type=csv -f _id,uid,page,date -o log_user_access_ ...

  4. Selenium操作之滚动条

    在用Selenium做UI自动化时,经常会遇到有些元素找不到之类的问题,但是自己的代码并没有错,元素就是找不到,这是为什么呢?原因很简单,由于页面内容较多,有些内容需要下拉滚动条才会显示,这里介绍一种 ...

  5. Excel函数sumproduct应用案例-多条件求和

    作者:iamlaosong 越来越认为sumproduct这个函数实用,过去用sum组函数.改起来复制起来都麻烦,sumif在条件多的时候也认为不方便. 如今改用sumproduct函数,就简单多了. ...

  6. Struts2的简单使用

    一.准备工作及实例 1.解压struts-2.1.6-all.zip apps目录:struts2自带的例子程序 docs目录:官方文档. lib 目录:存放所有jar文件. Src 目录:源文件存放 ...

  7. 我不会OOO,仍然可以XXX_转

    转自:http://blog.csdn.net/absurd 按照<审死官>里的读法,标题可以读着:答复:我不会圈圈圈,仍然可以叉叉叉.圈圈叉叉并不特指某个东西,而是一个通配符.代表诸如: ...

  8. 海康网络摄像机调用SDK解码Java版

    两个回调函数: FRealDataCallBack 实现预览回调数据 DecCallBack 解码回调函数 在HCNetSDK.java补充相关函数和结构声明 //播放库函数声明,PlayCtrl.d ...

  9. tcpdf

    将文档整为pdf格式文档 网址:http://www.tcpdf.org/examples.php

  10. VC++ Debug格式化数值显示

    When you watch variables in the Watch or Quick Watch window, the values are displayed using the defa ...