指针与引用
1️⃣ 指针什么是指针?指针: 指向另外一种类型的复合类型。 指针的大小及用法?在 64 位计算机中,指针占 8 个字节空间。 1234567891011#include<iostream>using namespace std;int main(){ int *p = nullptr; cout<<sizeof(p)<<endl; // 8 char *p1= nullptr; cout<<sizeof(p1)<<endl; // 8 return 0;} 指针的用法 指向普通对象的指针 常量指针 函数指针 指向对象成员的指针,包括指向对象成员函数的指针和指向对象成员变量的指针。 this 指针:指向类的当前对象的指针常量。 什么是野指针和悬空指针? 悬空指针 若指针指向一块内存空间 当这块内存空间被释放后,该指针依然指向这块内存空间 此时,称该指针为”悬空指针”。 123void *p = malloc(size);free(p); // 此时,p...
DNS 模块
1️⃣ 概述 在 sylar 项目中,**DNS 模块** 并不是 “只负责把域名解析成 IP” ,它的定位更接近于一个轻量级的 服务地址管理模块。 负责把 服务名 解析成 可用的后端地址; 承担 地址可用性判断、连接复用 以及 周期刷新 等职责。 从架构上看,这个模块实际上站在 “服务发现” 和 “连接管理” 的交界处,而不仅仅是传统意义上的 DNS 查询层。 2️⃣ AddressItem 如果说 Dns 负责管理一个服务对应的多个可选节点,那么 AddressItem 负责管理其中某一个具体节点(ip:port)的运行状态、健康检查结果以及连接池。 它的核心作用不是保存一个 ip:port,而是将 地址 抽象成一个可被调度、可被探活、可被复用的后端节点。 也就是说,在整个 DNS 模块中,真正参与 可用性判断 和 连接复用 的最小单位,不是 Address,而是 AddressItem。 设计思想 服务中的每个地址必须有自己的运行时状态 同一个服务名可能解析出针对该服务的多个...
HttpServer 模块
1️⃣ 概述在 sylar 框架中,HttpServer 是 TcpServer 的核心派生类,也是整个框架在 Web 开发领域的直接入口。如果说 TcpServer 负责的是 底层 的 “连接管理”,那么 HttpServer 负责的就是 “业务协议生命周期的全链路治理”。 HttpServer 不仅继承了 TcpServer 高并发、协程驱动 的优良基因,还引入了现代 Web 框架必备的 SSL 安全通信、中间件插件化、**Session 状态管理** 以及 Servlet 路由分发 等高级特性。 2️⃣ 设计核心HttpServer 的 核心逻辑 高度凝练在重写的 handleClient 方法中。 handleClient 将 socket 接收到的 Http 请求 转化成最终的 HTTP 响应,这其中经历了一套标准化的 “流水线” 操作: 安全加固 (SSL/TLS): 识别连接属性。若是 HTTPS 请求,则在最前端完成 非对称加密握手 逻辑(doHandShake),确保后续数据在加密流(SslSocketStream)中传输。 状态化封装...
TcpServer 模块
1️⃣ 概述在高性能网络框架中,TcpServer 模块往往处于 “承上启下” 的核心地位: 向下 封装了底层的 Socket 套接字细节, 向上 为各类 应用层协议 提供基础的连接管理和数据传输能力。 在 sylar 框架中,TcpServer 是一个高层次的封装,旨在提供一个 简单、稳定 且 支持多核并发 的 TCP 服务器基类。TcpServer 深度集成了 协程调度器 (IOManager) 和 套接字封装 (Socket),使得开发者可以专注于业务逻辑,而无需处理复杂的非阻塞 I/O 和多线程竞争。 2️⃣ 设计理念在 sylar 框架中,TcpServer 不仅仅是一个简单的套接字监听器,它是底层网络组件与复杂业务协议之间的核心桥梁。其架构设计的核心灵魂在于:通过高度解耦实现极致的并发效率与扩展性。 基于 Reactor 模式的双调度器架构这是 TcpServer 高并发能力的核心。它将网络事件处理划分为两个阶段,并允许通过不同的 IOManager 进行物理隔离: Accept 调度器:...
HOOK 模块
1️⃣ 什么是 HOOKHOOK ,中文简称:钩子 ,是对 函数/系统调用 API 进行一次封装。主要是将其封装成一个与原始的 函数/系统调用 API 同名的接口。 调用这个接口的时候,会 先进行封装的操作,再执行 原始 的 函数/系统调用API sylar 中的 HOOK,就是为了在不重写代码的情况下,把原有代码中的 同步 socket api 都转换为 异步 操作,以提升性能。 还可以用 C++ 的子类重载来理解 HOOK。在 C++ 中,子类在重载父类的同名方法时,一种常见的实现方式是子类先完成自己的操作,再调用父类的操作,如下: 12345678910111213141516class Base {public: void Print() { cout << "This is Base" << endl; }}; class Child : public Base {public: ///...
IOManager 模块
1️⃣ 什么是 IOManager 模块IOManager 模块可以理解为 Sylar 框架里的“协程版 I/O 事件循环 + 调度中枢”。它把 Linux 的 epoll 事件机制和协程调度器 Scheduler 融合在了一起。 当某个文件描述符 socket、pipe 等变得可读/可写时,IOManager 不会像传统 Reactor 那样直接在 epoll 线程里执行回调,而是把对应的回调函数或协程 Fiber 重新投递到调度器队列中,由线程池里的工作线程去执行。这样一来,业务逻辑可以用“同步写法”的协程风格组织,却能获得“异步 I/O”的高并发能力。 更具体地说,IOManager 维护了一个 FdContext 表,用来记录每个 fd 关注的读/写事件以及事件触发后要执行的回调函数或等待中的协程。它内部的 idle() 协程长期阻塞在 epoll_wait 上 一旦事件到来,就通过 triggerEvent() 将任务调度出去;同时它还继承 TimerManager,把定时器超时回调也纳入同一套调度体系,实现“IO 事件 +...
定时器模块
1️⃣ 什么是定时器定时器( Timer )本质上就是一种“按时间触发任务”的机制:你把一个任务 task 交给它,并告诉它“多久以后执行”或者“每隔多久执行一次”,定时器负责在合适的时间点把这个任务触发出来。 你可以把 Timer 理解成一个“闹钟”,而 TimerManager 就是“闹钟管理器”:你只负责设定时间和要做的事,到点后由它统一唤醒并执行对应任务。 在服务器/网络框架(比如 Sylar )里,定时器通常用来做这些事: 超时控制:连接超时、读写超时、RPC 超时重试 周期任务:心跳包、定期统计、定期清理缓存/过期会话 延迟执行:延迟关闭连接、延迟回收资源、延迟投递任务 事件循环协作:让 epoll/select 等 I/O 等待不会“傻等”,而是能在最近的定时点醒来。具体来说,事件循环会通过 getNextTimer() 计算“距离最近一次定时任务还要等多久”,并把这个时间作为 epoll_wait 的 timeout,这样既能等待 I/O 事件,又不会错过定时器到期触发。 2️⃣ 整体框架 3️⃣...
协程调度模块
1️⃣ 什么是协程调度器?协程调度器(Scheduler)本质上是把“要运行的协程/任务”分配到“可用的线程”上执行的调度中心。在 Sylar 里它封装的是一种 N-M 调度模型:N 个协程(Fiber / 回调函数)复用 M 个线程。调度器内部维护一个线程池和任务队列,外部通过 schedule() 把 Fiber 或 std::function<void()> 投递进来;当队列从空变为非空时,调度器会通过 tickle() 唤醒处于 idle() 的空闲线程/空闲协程去取任务执行。这样做的好处是:协程切换发生在用户态、成本低,同时又能利用多线程把不同协程并行跑起来,实现高并发下的高效调度与资源利用。 2️⃣ 整体框架图 3️⃣ 代码类图 4️⃣...
协程模块
1️⃣ 什么是协程?协程是一种比线程更轻量级的用户态并发单位,可以在一个线程内部并发执行多个任务,并且支持在任务之间进行主动挂起与恢复,从而实现看起来像并行实际上是串行的异步逻辑。 2️⃣ ucontext在 sylar 框架中,协程 Fiber 是基于 Linux 提供的 <ucontext.h> 实现的,该头文件中的 API 提供了保存、切换、恢复程序执行上下文的能力,允许用户在用户态实现轻量级的协程调度机制。 概述ucontext 是 POSIX 标准中定义的一组函数,用于实现用户级上下文切换。它允许程序保存和恢复执行上下文(如寄存器、程序计数器、栈等),常用于实现协程、轻量级线程或任务调度等功能。以下是对 ucontext 的详细介绍,并结合代码进行说明。 ucontext 是实现协程的一种方式。因为协程本质上就是一种用户级的线程, 既然是一种特殊的线程, 其上下文切换的实现方式应该和线程的上下文切换类似, 也需要保存必要的寄存器、程序计数器、栈等信息。 核心功能ucontext...
线程模块
线程模块线程的作用 在现代 C++ 网络服务器框架中,线程模块是实现并发处理、任务调度和系统资源充分利用的核心组件。Sylar 框架中的线程模块(Thread 类)封装了 POSIX 的 pthread 接口,简化了线程的创建、命名、同步与生命周期管理。 整体框架 模块解析私有成员变量 m_name :当前子线程的名字,在构造函数中我们需要给每一个线程赋予名字。 m_id :当前子线程的真实内核级线程ID,Linux 下使用 pid_t 唯一标识一个线程。 m_thread :当前子线程的线程标识符,用于表示一个线程对象。 m_cb :当前子线程绑定的回调函数,同样在构造函数中需要给每一个线程赋予它们所需要执行的函数 m_semphore :当前子线程的信号量,用于进行子线程和主线程之间的同步。 重要成员函数 构造函数 12345678910111213141516Thread::Thread(std::function<void()> cb, const std::string &name) : m_cb(cb) ,...
