news 2026/5/28 20:30:39

C++ 高性能网络服务骨架(二)—— 线程池接入:accept 与 worker 分离

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++ 高性能网络服务骨架(二)—— 线程池接入:accept 与 worker 分离

这一篇要解决什么问题?

在第一篇里,我们实现了一个最简单的 TCP 服务端:

accept → read → write → close

问题是:

所有请求串行执行

也就是说:

  • 一个慢请求 → 卡住后面所有请求
  • 服务端几乎没有并发能力

本篇目标

把模型升级为:

主线程: accept 新连接 ↓ 把连接丢给线程池 ↓ worker 线程处理请求

👉 核心变化:

accept 和请求处理解耦

一、整体架构图(非常重要)

客户端 │ ▼ ┌────────────┐ │ 主线程 │ ← 只负责 accept └────────────┘ │ ▼ ┌────────────┐ │ 线程池队列 │ └────────────┘ │ ▼ ┌────────────┐ │ worker线程 │ ← read / write / close └────────────┘

二、为什么必须这样拆?

❌ 错误模型(第一篇)

accept → read → write → close 👉 一个连接没处理完,accept 就不能继续

✅ 正确模型(本篇)

accept → 任务入队 → worker处理 👉 主线程永远在“接活”

三、核心思想(一定要记住)

线程池不是工具,而是服务端的执行引擎

分工模型

角色职责
主线程accept 连接
线程池调度任务
worker线程处理请求

四、核心改造点

我们只改一件事:

第一篇代码:

int client_fd = accept(...); // 直接处理 read(client_fd, ...); write(client_fd, ...); close(client_fd);

改成:

int client_fd = accept(...); // 丢给线程池 pool.submit([client_fd]() { // read / write / close });

👉 就这一行,完成架构升级。

五、完整代码(线程池接入版)

👉 假设你已经有 ThreadPool(上一章写的)

#include <iostream> #include <cstring> #include <unistd.h> #include <arpa/inet.h> #include "ThreadPool.h" // 你之前实现的线程池 void handle_client(int client_fd) { char buffer[1024] = {0}; read(client_fd, buffer, sizeof(buffer)); std::cout << "Received:\n" << buffer << std::endl; const char* response = "HTTP/1.1 200 OK\r\n" "Content-Length: 13\r\n" "\r\n" "Hello, World!"; write(client_fd, response, strlen(response)); close(client_fd); } int main() { // 1. 创建线程池 ThreadPool pool(4, 100); // 2. 创建 socket int server_fd = socket(AF_INET, SOCK_STREAM, 0); sockaddr_in addr{}; addr.sin_family = AF_INET; addr.sin_port = htons(8080); addr.sin_addr.s_addr = INADDR_ANY; bind(server_fd, (sockaddr*)&addr, sizeof(addr)); listen(server_fd, 10); std::cout << "Server running on port 8080..." << std::endl; while (true) { sockaddr_in client_addr{}; socklen_t len = sizeof(client_addr); int client_fd = accept(server_fd, (sockaddr*)&client_addr, &len); // ⭐ 核心:丢给线程池 pool.submit([client_fd]() { handle_client(client_fd); }); } return 0; }

六、流程再走一遍(必须脑子有图)

客户端请求 ↓ 主线程 accept ↓ 得到 client_fd ↓ submit 到线程池 ↓ worker 线程执行 handle_client ↓ read → write → close

七、关键细节(面试必问)

1️⃣ 为什么 client_fd 可以传给线程池?

pool.submit([client_fd]() { ... });

👉 因为:

  • fd 是一个 int(值拷贝)
  • 每个连接独立

2️⃣ 为什么必须在 worker 里 close?

👉 因为:

  • 谁用谁关闭
  • 生命周期归 worker

3️⃣ 主线程为什么不能 read?

👉 因为:

会阻塞 accept

4️⃣ 这个模型算高并发吗?

👉 ❌ 不算

因为:

  • 还是阻塞 IO
  • 每个连接占一个线程

八、这个版本的瓶颈

问题 1:线程数量有限

1000连接 → 需要1000线程 ❌

问题 2:read 是阻塞的

客户端慢 → worker线程卡住

问题 3:上下文切换开销大

👉 所以:

这个模型只是过渡版本

九、这一篇真正的价值

不是“并发更快了”,而是:你第一次真正建立了这个认知:

accept ≠ 处理请求

👉 服务端的本质是:

连接接入层 + 执行层分离

十、对标 Java(再强化一次)

Java 写法

ExecutorService pool = ... while (true) { Socket client = server.accept(); pool.submit(() -> { handle(client); }); }

👉 一模一样。

十一、你现在完成了什么?

你已经:

✔ 从“单线程服务端” → “并发服务端”
✔ 从“同步模型” → “任务调度模型”
✔ 从“写代码” → “搭架构”

十二、下一步(关键升级)

现在的问题是:

❌ 一个连接仍然占一个线程

下一篇

👉《C++ 高性能网络服务骨架(三)》—— 请求分发、连接管理与服务骨架设计

下一篇会解决:

  • 请求解析(不是 raw read)
  • 响应封装
  • 错误处理
  • 日志体系
  • 连接生命周期管理

总结

这一篇你一定要记住一句话:

线程池 = 服务端执行引擎

主线程只负责:

接连接

worker 线程负责:

干活

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/23 2:01:47

Attu:Milvus向量数据库的可视化管理革命,让图像检索效率提升85%

Attu&#xff1a;Milvus向量数据库的可视化管理革命&#xff0c;让图像检索效率提升85% 【免费下载链接】attu The Best GUI for Milvus 项目地址: https://gitcode.com/gh_mirrors/at/attu 想象你正在构建一个图像检索系统&#xff0c;需要管理数百万张产品图片的向量数…

作者头像 李华
网站建设 2026/5/28 20:30:34

别再只会拖拽了!CocosCreator Button组件的5种高级交互实现(附完整代码)

CocosCreator Button组件深度交互实战&#xff1a;突破基础点击的5种高阶玩法 当你已经能熟练拖拽Button组件实现基础点击时&#xff0c;是时候解锁更丰富的交互可能了。本文将带你探索五种高级按钮交互模式&#xff0c;每种方案都附带可直接集成到项目的完整代码实现。 1. 长…

作者头像 李华
网站建设 2026/5/23 2:01:57

Cesium性能优化:你可能不知道的onTick事件监听器内存泄漏问题

Cesium性能优化&#xff1a;你可能不知道的onTick事件监听器内存泄漏问题 在构建长时间运行的WebGIS应用时&#xff0c;Cesium的流畅渲染往往被视为首要目标。但许多开发者忽略了一个隐形杀手——未被正确清理的onTick事件监听器。这些看似无害的代码片段&#xff0c;会在用户毫…

作者头像 李华
网站建设 2026/5/23 2:01:57

新手友好:在快马平台用AI代码轻松入门网鼎杯wp分析

作为一名刚接触网络安全的新手&#xff0c;第一次看到网鼎杯的writeup&#xff08;wp&#xff09;时&#xff0c;那些专业术语和复杂操作确实让我有点懵。后来发现InsCode(快马)平台能把这些高深的技术转化成可运行的代码示例&#xff0c;简直是新手福音。今天就用一个最简单的…

作者头像 李华
网站建设 2026/5/23 2:01:55

如何提升混合身份环境的威胁检测与响应水平?Cohesity帮到你!

混合身份环境成为攻击焦点&#xff0c;AD 与 Entra ID 安全告急对于多数企业&#xff0c;Active Directory (AD) 是本地应用身份验证与授权的支柱&#xff0c;Microsoft Entra ID 将信任延伸至云端和 SaaS 应用。一旦 AD 或 Entra ID 遭到破坏&#xff0c;所有应用、用户、系统…

作者头像 李华