CppGuide社区 CppGuide社区
首页
  • 🔥最新谷歌C++风格指南(含C++17/20)
  • 🔥C++17详解
  • 🔥C++20完全指南
  • 🔥C++23快速入门
  • C++语言面试问题集锦
  • 🔥交易系统开发岗位求职与面试指南 (opens new window)
  • 第1章 高频C++11重难点知识解析
  • 第2章 Linux GDB高级调试指南
  • 第3章 C++多线程编程从入门到进阶
  • 第4章 C++网络编程重难点解析
  • 第5章 网络通信故障排查常用命令
  • 第6章 高性能网络通信协议设计精要
  • 第7章 高性能服务结构设计
  • 第8章 Redis网络通信模块源码分析
  • 第9章 后端服务重要模块设计探索
  • 🚀 全部章节.pdf 下载 (opens new window)
  • 源码分析系列

    • leveldb源码分析
    • libevent源码分析
    • Memcached源码分析
    • TeamTalk源码分析
    • 优质源码分享 (opens new window)
    • 🔥远程控制软件gh0st源码分析
  • 从零手写C++项目系列

    • 🔥C++游戏编程入门(零基础学C++)
    • 🔥使用C++17从零开发一个调试器 (opens new window)
    • 🔥使用C++20从零构建一个完整的低延迟交易系统 (opens new window)
    • 🔥使用C++从零写一个C语言编译器 (opens new window)
    • 🔥从零用C语言写一个Redis
  • 🔥Windows 10系统编程
  • 🔥Linux 5.x内核开发与调试 完全指南 (opens new window)
  • TCP源码实现超详细注释版.pdf (opens new window)
  • Go语言特性

    • Go系统接口编程
    • 高效Go并发编程
    • Go性能调优
    • Go项目架构设计
  • Go项目实战

    • 🔥使用Go从零开发一个数据库
    • 🔥使用Go从零开发一个编译器 (opens new window)
    • 🔥使用Go从零开发一个解释器 (opens new window)
    • 🔥使用Go从零开发一个解释器 (opens new window)
    • 🔥用Go从零写一个编排器(类Kubernetes) (opens new window)
Rust编程指南
  • SQL零基础指南
  • MySQL开发与调试指南
GitHub (opens new window)
首页
  • 🔥最新谷歌C++风格指南(含C++17/20)
  • 🔥C++17详解
  • 🔥C++20完全指南
  • 🔥C++23快速入门
  • C++语言面试问题集锦
  • 🔥交易系统开发岗位求职与面试指南 (opens new window)
  • 第1章 高频C++11重难点知识解析
  • 第2章 Linux GDB高级调试指南
  • 第3章 C++多线程编程从入门到进阶
  • 第4章 C++网络编程重难点解析
  • 第5章 网络通信故障排查常用命令
  • 第6章 高性能网络通信协议设计精要
  • 第7章 高性能服务结构设计
  • 第8章 Redis网络通信模块源码分析
  • 第9章 后端服务重要模块设计探索
  • 🚀 全部章节.pdf 下载 (opens new window)
  • 源码分析系列

    • leveldb源码分析
    • libevent源码分析
    • Memcached源码分析
    • TeamTalk源码分析
    • 优质源码分享 (opens new window)
    • 🔥远程控制软件gh0st源码分析
  • 从零手写C++项目系列

    • 🔥C++游戏编程入门(零基础学C++)
    • 🔥使用C++17从零开发一个调试器 (opens new window)
    • 🔥使用C++20从零构建一个完整的低延迟交易系统 (opens new window)
    • 🔥使用C++从零写一个C语言编译器 (opens new window)
    • 🔥从零用C语言写一个Redis
  • 🔥Windows 10系统编程
  • 🔥Linux 5.x内核开发与调试 完全指南 (opens new window)
  • TCP源码实现超详细注释版.pdf (opens new window)
  • Go语言特性

    • Go系统接口编程
    • 高效Go并发编程
    • Go性能调优
    • Go项目架构设计
  • Go项目实战

    • 🔥使用Go从零开发一个数据库
    • 🔥使用Go从零开发一个编译器 (opens new window)
    • 🔥使用Go从零开发一个解释器 (opens new window)
    • 🔥使用Go从零开发一个解释器 (opens new window)
    • 🔥用Go从零写一个编排器(类Kubernetes) (opens new window)
Rust编程指南
  • SQL零基础指南
  • MySQL开发与调试指南
GitHub (opens new window)
  • 第1章高频C++11重难点知识解析

  • 第2章Linux GDB高级调试指南

  • 第3章C++多线程编程从入门到进阶

  • 第4章C++网络编程重难点解析

  • 第5章网络通信故障排查常用命令

  • 第6章高性能网络通信协议设计精要

  • 第7章高性能服务结构设计

    • 7.1 网络通信组件的效率问题
    • 7.2 最原始的服务器结构
    • 7.3 一个连接一个线程模型
    • 7.4 Reactor 模式
    • 7.5 one thread one loop 思想
    • 7.6 收数据与发数据的正确姿势
    • 7.7 发送/接收缓冲区设计要点
    • 7.8 网络库的分层设计
    • 7.9 后端服务中的定时器设计
    • 7.10 业务数据处理一定要单独开线程吗
    • 7.11 侵入式程序结构与非侵入式程序结构
    • 7.12 带有网络通信模块的服务器的经典结构
  • 第8章Redis 网络通信模块源码分析

  • 第9章后端服务重要模块设计探索

  • C++后端开发进阶
  • 第7章高性能服务结构设计
zhangxf
2023-04-05

7.4 Reactor 模式

目前存在很多的网络通信库,从 C/C++ 的 libevent 库,到 Java 的 Netty 框架,再到 python 的 Twisted 库等,目前主流的网络库使用的都是 Reactor 模式(中文译作: 反应器模式或反射器模式)。那么到底什么是 Reactor 模式呢?Reactor 模式有什么优点?Reactor 模式英文解释如下:

The reactor design pattern is an event handling pattern for handling service requests delivered concurrently to a service handler by one or more inputs. The service handler then demultiplexes the incoming requests and dispatches them synchronously to the associated request handlers.

翻译成中文的意思就是:

反应器设计模式( Reactor pattern )是一种事件处理设计模式,该模式可以将一个或多个 IO 请求服务并发地传递给服务处理器,即当( IO 处理)请求抵达后,服务处理程序使用多路复用技术,然后同步地派发这些请求至相关的请求处理程序。

流程图如下:

从流程图上来看,这个设计模式看起来很简单,其背后却蕴含着不简单的设计思想。那么上图中到底蕴含着什么样的思想奥妙呢?它解决了计算机世界中普遍存在的一个问题,即请求太多,资源太少。也就是说一个对外服务程序,其接收的各种输入输出请求的数量可能是非常多的,然后由于处理能力有限,其处理这些请求的资源数量是有限的。诚然,大千世界也是这样,如一个公园的游客容量是有限的,而游客数量可能是无限的;一个饭店的座位是有限的,而顾客可能是无限的;一个国家的领土是有限的,其人口可能是无限增长的。所以上图中输入输出请求数量之和一般会远远大于处理程序数量,而多路复用器(IO Demultiplexer)将这些数量众多的输入输出请求分发给有限的处理程序。

所以一个 Reactor 模式结构一般包含以下模块:

  • 资源请求事件(Resource Request)

  • 多路复用器与事件分发器(IO Demultiplexer & Event Dispatcher)

  • 事件处理器(EventHandler)

我们以目前大多数饭店的运营模式这样一个生活中的例子来说明一下reactor模式,顾客去饭店吃饭,由于客户较多,饭店的服务员数量有限,所以饭店都是某个服务员负责某几桌客户,当顾客有需求时(点菜、结账等),可以把需要告诉服务员,由服务员去把这些需求再转发给其他相关人员(点菜转发给厨房,结账交给收银)。如此操作,在即使饭店顾客爆满时,靠几个服务员也能有条不紊地运转着整个饭店。

这是很简单的生活例子,却有着最朴素的思想,在对应具体的服务器程序技术上来说,以 socket 的读写为例,输入输出请求就是 socket 上有数据可读或者需要往 socket 上写入数据,而 IO 复用器就对应着操作系统的相关 API,Windows 操作系统上有 select 技术(函数),Linux 上有 select 函数、poll 函数、epoll 模型(实际对应 epoll_wait)。使用这些IO复用技术之后,Reactor 模式对应的流程图就变成了如下结构:

上次更新: 2025/04/01, 20:53:14
7.3 一个连接一个线程模型
7.5 one thread one loop 思想

← 7.3 一个连接一个线程模型 7.5 one thread one loop 思想→

最近更新
01
第二章 关键字static及其不同用法
03-27
02
第一章 auto与类型推导
03-27
03
C++语言面试问题集锦 目录与说明
03-27
更多文章>
Copyright © 2024-2025 沪ICP备2023015129号 张小方 版权所有
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式