Reactor模型 + muduo网络库日志打印

发布时间:2026/9/29 16:21:16

Reactor模型 + muduo网络库日志打印 一个好的服务器的设计一个良好的服务器应该怎么设计在之后的文章里面我不仅仅会写网络库也会解析sylar服务器框架所以一个良好的服务器设计很重要。我们现在都是多核的计算机所以多线程服务的问题就转化成了如何设计一个高效且易于使用的eventLoop然后每一个线程run一个eventLoop就可以了。eventLoop是non-blocking网络编程的核心而且non-blocking一般都和IO多路复用一起连用。原因有几个没有人会一直轮询某个non-blocking的IO这样子很费CPU如果我们选择阻塞像read/write/connect/accept 都有可能意外的阻塞当前的线程导致当前线程就没有办法在socket处理其他的事情了。Reactor我们在书写网络库的时候一定要好好的理解Reactor模型Reactor模型里面有4个部分event事件reactor反应堆demultiplex事件分发器eventhandler事件处理器。当有事件event和handler注册时就会进入reactorreactor里面维护了所有的event集合reactor会通过epoll_ctl()来注册发生的事件在事件分发器里面调整event并且启动反应堆开启epoll_wait如果epoll_wait监听到有事件产生事件分发器就会返回event给reactor。为什么要返回呢因为事件的发生就意味着需要执行回调函数那么我们的回调函数全部都在反应堆里面。所以reactor就像一个大脑可以开启监听epoll_wait也就是事件分发器也会调用回调函数也就是EventHandler这个就是muduo库的reactor的模型不过这里有一点点的不一样这里的reactor吧reactor和demultiplex合二为一了我们可以简单的陈述一下子这个过程。当服务器开启之后会创建一个mainLoop这个mainLoop就是监听所有客户端的接口。因为现在的计算机都是多核多个CPU所以我们肯定不会是单线程运行每个线程都会对应一个CPU。当客户端发来信息我们计算机后端需要进行接受read解码decode编码encode最后发送给客户端。mainLoop里面有一个acceptor这个有两个部分的功能一个是listen监听一个是分发给subLoop子reactor这样子就可以有多个线程进行工作了。日志打印日志的打印是一个项目必备的部分当项目发生错误的时候我们可以快速的定位。我们打印器是一个单例模式然后每当使用打印器的时候定义其打印水平一遍打印出不同的东西。enum LogLevel { INFO, ERROR, FATAL, DEBUG, }; class Logger { public: static Logger* getInstance(); void setLogLevel(int level); void log(std::string msg); private: Logger(){} Logger(const Logger) delete; void operator(const Logger) delete; private: int m_logLevel; };#include ../include/Logger.h Litguidyo::Logger* Litguidyo::Logger::getInstance() { static Logger logger; return logger; } void Litguidyo::Logger::setLogLevel(int level) { m_logLevel level; } void Litguidyo::Logger::log(std::string msg) { switch (m_logLevel) { case INFO: std::cout [INFO]; break; case ERROR: std::cout [ERROR]; break; case FATAL: std::cout [FATAL]; break; case DEBUG: std::cout [DEBUG]; break; default: break; } // 打印时间 std::cout print time : msg std::endl; }为了更加方便使用打印日志我们一般都会定义很多宏。打印日志很多时候都是do while的结构防止出现一些语句的匹配错误debug我们一般都会在配置的时候确定是否开启所以要加ifdef DEBUG在出现致命错误的时候整个程序都必须要停止所以会有exit-1#define LOG_INFO(logmsgFormat, ...) \ do { \ Logger* logger Logger::getInstance(); \ logger-setLogLevel(INFO); \ char buf[1024] {0}; \ snprintf(buf, sizeof(buf), logmsgFormat, ##__VA_ARGS__); \ logger-log(buf); \ } while(0) #define LOG_ERROR(logmsgFormat, ...) \ do { \ Logger* logger Logger::getInstance(); \ logger-setLogLevel(ERROR); \ char buf[1024] {0}; \ snprintf(buf, sizeof(buf), logmsgFormat, ##__VA_ARGS__); \ logger-log(buf); \ } while(0) #ifdef MUDBUG #define LOG_DEBUG(logmsgFormat, ...) \ do { \ Logger* logger Logger::getInstance(); \ logger-setLogLevel(DEBUG); \ char buf[1024] {0}; \ snprintf(buf, sizeof(buf), logmsgFormat, ##__VA_ARGS__); \ logger-log(buf); \ } while(0) #else #define LOG_DEBUG(logmsgFormat, ...) #endif #define LOG_FATAL(logmsgFormat, ...) \ do { \ Logger* logger Logger::getInstance(); \ logger-setLogLevel(FATAL); \ char buf[1024] {0}; \ snprintf(buf, sizeof(buf), logmsgFormat, ##__VA_ARGS__); \ logger-log(buf); \ exit(-1); \ } while(0) }总结本篇文章到这里就结束了希望可以帮助大家理解~~~
延伸阅读

更多相关文章

2026/9/28 16:31:33

Spring事务失效的八大场景与解决方案

1. Spring事务失效场景深度解析从事Java开发这些年,Spring事务管理就像个熟悉的陌生人——看似简单,实则暗藏玄机。最近团队里连续出现几起因事务失效导致的线上事故,让我决定系统梳理这个"老熟人"的脾气秉性。下面这些坑&#xff…

2026/9/27 2:17:40

联想记忆法在语言学习中的应用与技巧

由于提供的输入内容过于简略(项目标题为"2026.03.11四级联想 第三节",其余字段均为空),且缺乏明确的主题、技术背景或应用场景说明,无法生成符合要求的专业博文。为保障内容质量与安全性,建议补充…

2026/9/26 21:47:10

springboot单位考勤系统的管理设计与实现

课题背景 随着信息技术的快速发展,传统的人工考勤管理方式逐渐暴露出效率低、易出错、数据难以统计分析等问题。尤其在企事业单位、教育机构等场景中,考勤管理涉及大量人员数据的记录、存储和分析,传统纸质签到或简单的电子表格已无法满足现代…

2026/9/29 16:20:13

C语言栈和队列的实现:从顺序存储到链式存储与环形队列

写代码这么多年,我有个习惯:新接触一门语言,第一件事不是去背语法,而是先把 栈 和 队列 写一遍。尤其是C语言,没有那些现成的容器可以用,一切都要自己动手造轮子。C语言栈和队列的实现,看起…

2026/9/29 16:20:13

SQL JOIN中ON与WHERE的语义差异:LEFT JOIN丢行排查指南

先说一个我经常在代码评审里碰到的现象:一条 SQL 从写出来到跑通,很多同学其实没搞明白 ON 和 WHERE 的区别。他们日常写的 INNER JOIN 里,这两种条件放哪结果都一样,于是慢慢形成了一个"反正都能用"的印象。等哪天真要…

2026/9/29 16:20:13

Mac无损播放器怎么选?Audirvana、Amarra、Foobar2000对比与DSD配置指南

1. 三款播放器的定位差异与选型逻辑1.1 为什么Mac上的无损播放器选择这么少刚从Windows转到Mac那会儿,我第一反应就是找Foobar2000的Mac版。在Windows上用了十几年,界面虽然朴素,但DSD源码输出、歌词插件、皮肤定制这些功能一个不少&#xff…

2026/9/29 16:20:13

PostgreSQL与pgAdmin入门:从下载安装到图形化配置基础操作指南

最近帮一个同事把整套 PostgreSQL 环境从旧库迁到新服务器,整个过程正好把 PostgreSQL 安装、pgAdmin 配置和日常基础操作完整走了一遍。迁移那几天踩了不少坑,也顺手总结了一套适合新手的操作流程。这篇东西就围绕 PostgreSQL 的图形化管理工具 pgAdmin…

2026/9/29 16:20:13

SQL注入与参数化查询:从原理到多语言实战的防御指南

1. 为什么SQL注入屡禁不止——先理解攻击者的视角1.1 SQL注入的本质:从“万能密码”说起我经常在技术群里看到新手问“SQL注入是不是已经过时了”。实际上,每一年的漏洞报告里,SQL注入依然稳定地占据OWASP Top 10的一席之地。很多程序员觉得只…

2026/9/29 16:15:12

SQL优化实战:从执行顺序到索引、慢SQL排查与性能调优

先说个我上周刚处理完的线上事故。客户SaaS系统下午三点突然卡死,页面转圈,订单列表都打不开。我上去一看数据库CPU直接拉满,抓出来的那条SQL把三张大表做了三个JOIN,每张表几百万行,WHERE条件里还套了函数&#xff0c…

2026/9/29 11:07:23

东莞市品牌网站建设报价常见报错与解决

东莞品牌网站建设报价单背后:一份保姆级建站教程避坑实录 网站做好了没人访问,这大概是很多老板最头疼的事。花了大几万做的品牌站,上线后流量惨淡,比路边摊还冷清。别急着骂外包公司,很多“东莞品牌网站建设报价”里藏着不少猫腻,比如用模板站冒充定制…

2026/9/28 6:05:15

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/29 7:00:49

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/29 0:04:04

AI Evals实战指南:从零搭建LLM应用评估体系与CI/CD集成

1. 为什么AI Evals值得你花时间搞明白做LLM应用的人,迟早会撞上同一堵墙:模型输出飘忽不定,今天答得好好的,明天换个问法就胡说八道。你改了一版提示词,感觉好像好了点,但到底好了多少?说不清。…

2026/9/29 0:04:04

Java采购管理系统实战:从数据库设计到事务一致性

简介:这是一套面向Java Web初学者与课程设计者的采购管理系统完整源码,采用JSP技术搭建,配合MySQL数据库,用于解决企业采购信息的管理问题,适合作为毕业设计、课程大作业或进销存类项目的参考模板。系统实现了用户登录…

2026/9/29 3:53:39

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/29 9:46:12

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/29 6:36:14

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑