当前位置: 首页 > article >正文

【Linux 实战 - 25】Reactor 事件驱动模型原理与实现

在高并发网络编程中如何高效处理成千上万的连接是核心挑战。Reactor反应器模式作为一种经典的事件驱动设计模式通过 I/O 多路复用技术实现了单线程或多线程高效处理多连接的目标被广泛应用于 Nginx、Redis、Netty 等高性能网络框架中。一、什么是 Reactor 模式Reactor 模式是一种基于事件驱动的并发处理模式其核心思想是将 I/O 事件的监听、分发与业务处理解耦通过I/O 多路复用如 epoll、select监听多个文件描述符fd的事件当事件就绪时将其分发给对应的事件处理器Handler执行。传统多线程模型 vs Reactor 模型传统多线程模型每个连接创建一个线程资源消耗大并发上限低。Reactor 模型单线程或线程池通过 I/O 多路复用监听多连接事件就绪时才处理资源利用率高。二、Reactor 的核心组件Reactor 模式由 5 个关键部分组成组件作用Event Loop事件循环持续调用 I/O 多路复用器监听事件分发事件给处理器。DemultiplexerI/O 多路复用器如 epoll、select监听多个 fd 的读写事件。Event Handler事件处理器接口定义事件处理方法如handle_read()、handle_write()。Concrete Handler具体事件处理器实现 Event Handler 接口处理实际业务逻辑。Acceptor特殊的事件处理器处理新连接的建立accept并注册新 fd 到 Reactor。三、Reactor 的工作原理单线程版单线程 Reactor 是最基础的实现其工作流程如下初始化创建 Reactor、注册 Acceptor监听 socket 的读事件。事件循环调用epoll_wait()阻塞等待事件就绪。若就绪事件是新连接Acceptor 调用accept()建立连接将新 fd 注册到 Reactor。若就绪事件是数据可读 / 可写分发给对应的 Concrete Handler 处理。业务处理Handler 执行handle_read()读取数据、处理业务必要时注册写事件。四、基于 epoll 的 Reactor 实现C 语言示例以下是一个简化的单线程 Reactor 实现使用 epoll 作为 I/O 多路复用器支持 TCP 连接的建立与数据回显。1. 核心数据结构#include stdio.h #include stdlib.h #include string.h #include unistd.h #include sys/socket.h #include netinet/in.h #include sys/epoll.h #define MAX_EVENTS 1024 #define BUFFER_SIZE 1024 // 事件处理器接口 typedef struct EventHandler { int fd; void (*handle_read)(struct EventHandler *self); void (*handle_write)(struct EventHandler *self); char buffer[BUFFER_SIZE]; int buffer_len; } EventHandler; // Reactor结构体 typedef struct Reactor { int epoll_fd; struct epoll_event events[MAX_EVENTS]; EventHandler *handlers[MAX_EVENTS]; // 存储fd对应的处理器 } Reactor;2. Reactor 初始化与事件注册// 创建Reactor Reactor *reactor_create() { Reactor *reactor (Reactor *)malloc(sizeof(Reactor)); reactor-epoll_fd epoll_create1(0); memset(reactor-handlers, 0, sizeof(reactor-handlers)); return reactor; } // 注册事件到Reactor void reactor_register(Reactor *reactor, int fd, EventHandler *handler, uint32_t events) { struct epoll_event ev; ev.events events; ev.data.fd fd; epoll_ctl(reactor-epoll_fd, EPOLL_CTL_ADD, fd, ev); reactor-handlers[fd] handler; } // 事件循环 void reactor_run(Reactor *reactor) { while (1) { int n epoll_wait(reactor-epoll_fd, reactor-events, MAX_EVENTS, -1); for (int i 0; i n; i) { int fd reactor-events[i].data.fd; EventHandler *handler reactor-handlers[fd]; if (reactor-events[i].events EPOLLIN) { handler-handle_read(handler); // 处理读事件 } if (reactor-events[i].events EPOLLOUT) { handler-handle_write(handler); // 处理写事件 } } } }3. 具体事件处理器回显服务// 处理读事件回显数据 void echo_handle_read(EventHandler *self) { int n read(self-fd, self-buffer, BUFFER_SIZE); if (n 0) { close(self-fd); free(self); return; } self-buffer_len n; // 注册写事件准备回显数据 struct epoll_event ev; ev.events EPOLLOUT; ev.data.fd self-fd; epoll_ctl(epoll_fd, EPOLL_CTL_MOD, self-fd, ev); } // 处理写事件发送回显数据 void echo_handle_write(EventHandler *self) { write(self-fd, self-buffer, self-buffer_len); // 重新注册读事件 struct epoll_event ev; ev.events EPOLLIN; ev.data.fd self-fd; epoll_ctl(epoll_fd, EPOLL_CTL_MOD, self-fd, ev); } // 创建回显处理器 EventHandler *echo_handler_create(int fd) { EventHandler *handler (EventHandler *)malloc(sizeof(EventHandler)); handler-fd fd; handler-handle_read echo_handle_read; handler-handle_write echo_handle_write; return handler; }4. Acceptor处理新连接void acceptor_handle_read(EventHandler *self) { struct sockaddr_in client_addr; socklen_t client_len sizeof(client_addr); int client_fd accept(self-fd, (struct sockaddr *)client_addr, client_len); // 创建回显处理器并注册到Reactor EventHandler *echo_handler echo_handler_create(client_fd); reactor_register(reactor, client_fd, echo_handler, EPOLLIN); } // 创建Acceptor EventHandler *acceptor_create(int listen_fd) { EventHandler *handler (EventHandler *)malloc(sizeof(EventHandler)); handler-fd listen_fd; handler-handle_read acceptor_handle_read; return handler; }5. 主函数int main() { // 创建监听socket int listen_fd socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in server_addr; memset(server_addr, 0, sizeof(server_addr)); server_addr.sin_family AF_INET; server_addr.sin_addr.s_addr htonl(INADDR_ANY); server_addr.sin_port htons(8080); bind(listen_fd, (struct sockaddr *)server_addr, sizeof(server_addr)); listen(listen_fd, 10); // 创建Reactor并注册Acceptor Reactor *reactor reactor_create(); EventHandler *acceptor acceptor_create(listen_fd); reactor_register(reactor, listen_fd, acceptor, EPOLLIN); // 运行事件循环 reactor_run(reactor); return 0; }五、Reactor 模式的优缺点优点高并发单线程处理多连接避免线程切换开销。解耦事件监听、分发与业务处理分离代码结构清晰。扩展性可通过多线程 Reactor主从 Reactor进一步提升性能。缺点单线程瓶颈若 Handler 处理耗时过长如 CPU 密集型任务会阻塞整个事件循环。依赖 I/O 多路复用需结合 epoll/kqueue 等系统调用跨平台性略差。六、总结Reactor 模式是高性能网络编程的基石通过事件驱动 I/O 多路复用实现了高效的并发处理。在实际应用中可根据需求选择单线程 Reactor适用于连接数少、业务逻辑简单的场景如 Redis。多线程 Reactor主 Reactor 处理连接从 Reactor 处理读写如 Netty。掌握 Reactor 模式是深入理解 Linux 网络编程与高性能框架的关键一步。下篇预告【Linux 实战 - 26】轻量级 HTTP 服务器原理与 C 语言 Socket 实现原创不易如果本文对你有帮助欢迎点赞、收藏、关注三连有任何问题都可以在评论区留言我会及时回复。

相关文章:

【Linux 实战 - 25】Reactor 事件驱动模型原理与实现

在高并发网络编程中,如何高效处理成千上万的连接是核心挑战。Reactor(反应器)模式作为一种经典的事件驱动设计模式,通过 I/O 多路复用技术实现了单线程(或多线程)高效处理多连接的目标,被广泛应…...

WorkshopDL:突破性多引擎架构重构Steam创意工坊生态体验

WorkshopDL:突破性多引擎架构重构Steam创意工坊生态体验 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 在当今游戏模组生态中,Steam创意工坊已成为玩家…...

CDK:云原生安全渗透测试的容器环境一体化工具解析

1. 项目概述:一个云原生时代的“瑞士军刀”如果你在云原生安全、渗透测试或者红队评估领域摸爬滚打过一段时间,一定会对“工具集”这个概念又爱又恨。爱的是,一个趁手的工具集能让你事半功倍,快速定位问题;恨的是&…...

【Linux 实战 - 26】轻量级 HTTP 服务器原理与 C 语言 Socket 实现

前言 HTTP 是互联网最核心的应用层协议,几乎所有网页、API、嵌入式 Web 控制都基于 HTTP 实现。本文从 HTTP 协议基础 讲起,使用 Linux C Socket 从零实现一个可运行、可扩展、轻量级 HTTP 服务器,适合学习网络编程、嵌入式 Web、后端原理。…...

AI智能体监控平台agentwatch:从可观测性到性能优化实战

1. 项目概述:一个面向AI智能体生态的监控与洞察工具最近在折腾AI智能体(Agent)相关的项目,发现一个挺有意思的现象:当你的智能体数量从几个增长到几十个甚至更多时,管理它们的状态、追踪它们的决策过程、分…...

Python自动化脚本断点续传下载实战:大文件处理完整指南

大家好,我是扣扣。今天来聊聊一个很实用的功能——断点续传下载。 为什么要关心断点续传? 你有没有遇到过这些情况: 下载一个大文件,下载到99%的时候网络断了,得从头再来 公司网络不稳定,几十MB的文件死活下载不下来 凌晨跑个定时任务下载数据,结果因为网络波动失败了…...

保姆级教程:手把手教你修改Material Studio的Perl交联脚本,适配你的自定义聚合物

深度定制Material Studio交联脚本:从环氧树脂到多元聚合物的Perl魔改指南 当你第一次在论文中看到那个神奇的环氧树脂交联脚本时,可能和我一样兴奋——终于不用手动跟踪每个反应位点了!但现实很快给了我们这些研究聚酰亚胺、聚氨酯等非环氧体…...

告别手动解析!用CANdb++制作DBC文件保姆级教程(附Intel/Motorola格式详解)

告别手动解析!用CANdb制作DBC文件保姆级教程(附Intel/Motorola格式详解) 在车载电子系统开发中,工程师们每天需要处理海量的CAN总线原始数据。这些以十六进制形式呈现的报文,就像一本没有词典的外语书籍——你能看到字…...

Taotoken模型广场在项目技术选型中的实际使用感受

Taotoken模型广场在项目技术选型中的实际使用感受 1. 模型广场的界面设计与信息组织 Taotoken模型广场采用分类清晰的布局设计,左侧导航栏按模型用途(如文本生成、代码补全、多模态等)和厂商进行分组。每个模型卡片展示关键信息&#xff1a…...

Reolink E1 Outdoor Pro 4K智能摄像头WiFi 6技术评测

1. Reolink E1 Outdoor Pro 4K智能安防摄像头深度评测作为一名长期测试各类安防设备的博主,我最近上手了Reolink最新推出的E1 Outdoor Pro 4K智能安防摄像头。这款产品最吸引我的地方在于它率先在消费级安防领域采用了WiFi 6技术——要知道目前市面上绝大多数同类产…...

秩序之舞——排序算法中的数字星河

一,引言 在计算机科学的世界里,排序是最基础、也最重要的核心算法之一。无论是日常开发中的列表数据整理、数据库查询的结果规整,还是电商平台商品价格、销量的智能排行,亦或是机器学习、大数据处理中的数据预处理环节&#xff0c…...

Docker生态资源精选列表:从入门到实战的完整指南

1. 项目概述:一个Docker生态的“藏宝图”如果你在容器技术领域摸爬滚打过一段时间,尤其是深度使用Docker,那你一定有过这样的经历:为了解决一个特定的问题,比如搭建一个高性能的日志收集栈,或者寻找一个轻量…...

租房党、学生党、居家党|2026年电钢琴按场景选购攻略,机型推荐

我发现很多新手在买电钢琴的时候,会陷入一个思维误区:只盯着价格和品牌,却完全没有思考过我会在哪里用它这个问题。结果要么买了个便携款放在家里嫌它太轻没质感,要么搬了台立式琴到宿舍发现根本没地方放。事实上,电钢…...

2026新手吉他选购指南:1000-1500 元热门吉他横评,初学者选哪把琴?

新手入门选吉他,1000-1500 元是兼顾性价比与使用体验的主流价位,这一区间的的四款吉他都是热门之选。几款琴各有侧重,有的胜在品控口碑,有的赢在价格亲民,但新手选琴的核心终究是材质稳定、手感友好、配套完善&#xf…...

基于RAG与向量搜索的本地语义文件搜索系统构建指南

1. 项目概述:当本地文件库遇上大语言模型如果你和我一样,电脑里塞满了各种文档、笔记、代码片段和PDF报告,每次想找点东西都得靠记忆或者全局搜索碰运气,那你一定理解那种“信息就在那里,但我就是找不到”的无力感。传…...

Redis分布式锁进阶第十五篇

Redis分布式锁进阶第十五篇:热点锁雪崩根治方案 分片隔离实战落地 大促峰值零卡顿优化一、本篇定位:高并发压垮Redis的最后解法前面十四篇,我们搞定了死锁、看门狗、主从丢锁、联锁乱序、监控巡检。第十五篇专门解决大促必现、排查最难、影…...

AntiDupl:如何用专业级图像去重工具高效管理你的数字资产

AntiDupl:如何用专业级图像去重工具高效管理你的数字资产 【免费下载链接】AntiDupl A program to search similar and defect pictures on the disk 项目地址: https://gitcode.com/gh_mirrors/an/AntiDupl 你是否曾因电脑中堆积如山的重复图片而感到困扰&a…...

Nuxt 学习笔记(三)

SEO 头部设置 基于 Unhead 提供 useHead 管理 <head>&#xff0c;也可在 nuxt.config.ts 的 app.head 中配置。 同时提供 useHeadSafe 来支持安全的头部修改策略 interface MetaObject {title?: string; // 文档标题titleTemplate?: string | ((title?: string) &…...

使用Taotoken聚合API为你的Node.js后端服务注入AI能力

使用Taotoken聚合API为你的Node.js后端服务注入AI能力 1. 统一接入多模型的技术方案 在现代Web应用开发中&#xff0c;智能对话功能已成为提升用户体验的重要组件。作为全栈开发者&#xff0c;我们经常面临模型选型与接入的挑战。Taotoken提供的OpenAI兼容API解决了这一痛点&…...

OpenWrt网易云音乐解锁插件:3分钟实现全屋音乐自由

OpenWrt网易云音乐解锁插件&#xff1a;3分钟实现全屋音乐自由 【免费下载链接】luci-app-unblockneteasemusic [OpenWrt] 解除网易云音乐播放限制 项目地址: https://gitcode.com/gh_mirrors/lu/luci-app-unblockneteasemusic 还在为网易云音乐中那些灰色的"无版权…...

从单片机到Linux内核:一文搞懂原子操作atomic_t的前世今生与实战

从单片机到Linux内核&#xff1a;一文搞懂原子操作atomic_t的前世今生与实战 在嵌入式开发领域&#xff0c;从单片机转向Linux内核开发就像从平静的湖泊驶向波涛汹涌的大海。习惯了在STM32上用__disable_irq()简单粗暴地解决并发问题的工程师&#xff0c;初次面对Linux内核的SM…...

豆包付费订阅背后,藏着一个反直觉的真相:给你顶配AI,你用得动吗?

豆包悄悄在App Store更新了付费订阅声明。68元/月&#xff0c;200元/月&#xff0c;500元/月&#xff0c;国产AI的"免费午餐"&#xff0c;正式宣告终结。这不是一条普通的商业新闻。字节扛了这么久&#xff0c;最终还是选了商业化。表面是商业压力&#xff0c;背后是…...

Arduino UNO SPE Shield:工业物联网通信解决方案

1. Arduino UNO SPE Shield项目概述作为一名长期从事工业自动化开发的工程师&#xff0c;当我第一次接触到Arduino UNO SPE Shield时&#xff0c;立刻意识到这款扩展板将为工业物联网(IIoT)项目带来革命性的便利。这款由Arduino官方推出的扩展板&#xff0c;通过Microchip LAN8…...

基于LangChain与Ollama的本地化网页摘要工具实践指南

1. 项目概述&#xff1a;一个基于本地大模型的网页摘要工具最近在折腾信息收集和整理&#xff0c;发现每天要看的网页和视频实在太多了&#xff0c;时间根本不够用。相信很多做研究、写报告或者单纯想高效获取信息的朋友都有同感。传统的摘要工具要么是云端服务&#xff0c;有隐…...

微信聊天记录解密终极指南:快速恢复被加密的珍贵数据

微信聊天记录解密终极指南&#xff1a;快速恢复被加密的珍贵数据 【免费下载链接】WechatDecrypt 微信消息解密工具 项目地址: https://gitcode.com/gh_mirrors/we/WechatDecrypt 你是否曾经因为手机损坏、微信重装或误删除而丢失了重要的聊天记录&#xff1f;当那些珍贵…...

多智能体协作平台AgentWall:从架构设计到工程实践

1. 项目概述&#xff1a;从“墙”到“智能体协作平台”的蜕变最近在开源社区里&#xff0c;一个名为agentwall/agentwall的项目引起了我的注意。乍一看这个标题&#xff0c;很容易让人联想到某种网络隔离或安全边界技术&#xff0c;毕竟“wall”这个词在技术领域通常指向防火墙…...

OpenUI深度解析:AI驱动界面生成从原理到实战部署

1. 项目概述&#xff1a;当AI学会“画”界面最近在跟几个做产品经理和前端开发的朋友聊天&#xff0c;大家不约而同地都在吐槽一件事&#xff1a;从想法到可交互的原型&#xff0c;这个链路太长了。产品经理用Figma画半天&#xff0c;交付给前端&#xff0c;前端还得吭哧吭哧地…...

文海问津项目日志(四)

本次主要实现了网关的错误归一化与统一 JSON Envelope功能目标所有失败请求都返回一致的 JSON 结构&#xff0c;便于前端统一处理错误 body 必含 requestId&#xff0c;便于定位链路网关级错误&#xff08;鉴权/限流/未知异常&#xff09;不依赖下游服务关键代码原文 解读1 统…...

Total War模组开发的现代化架构:深度解析Rusted PackFile Manager(RPFM)的技术实现

Total War模组开发的现代化架构&#xff1a;深度解析Rusted PackFile Manager&#xff08;RPFM&#xff09;的技术实现 【免费下载链接】rpfm Rusted PackFile Manager (RPFM) is a... reimplementation in Rust and Qt6 of PackFile Manager (PFM), one of the best modding t…...

多智能体系统架构设计:从隔离沙箱到编排引擎的工程实践

1. 项目概述&#xff1a;从零构建一个智能体协作与隔离平台最近在开源社区里&#xff0c;一个名为agentwall/agentwall的项目引起了我的注意。乍一看这个名字&#xff0c;你可能会联想到“智能体墙”或者“代理墙”&#xff0c;但它的核心远不止于此。简单来说&#xff0c;这是…...