以下是一个基于 C++ 实现、借鉴 muduo 网络库 的 One-Thread-One-Loop(一个线程一个事件循环) 模式的简易并发 TCP 服务器示例项目。该项目展示了如何使用多线程 + epoll 实现高性能、可扩展的事件驱动服务器模型。
🔧 项目概述
- 项目名称:MiniMuduoServer
- 模型模式:Reactor 模式(每个线程绑定一个事件循环)
- 通信方式:TCP
- 技术要点:
- 使用
epoll
实现 I/O 多路复用 EventLoop
负责事件派发ThreadPool
管理线程- 主线程仅负责
accept
,随后将连接分配给工作线程
- 使用
📁 项目结构
MiniMuduoServer/
├── main.cpp
├── EventLoop.h / cpp
├── Channel.h / cpp
├── TcpServer.h / cpp
├── TcpConnection.h / cpp
├── ThreadPool.h / cpp
├── Acceptor.h / cpp
└── utils.h / cpp
✨ 核心组件设计思路
1. EventLoop
(事件循环)
每个工作线程有一个 EventLoop
,绑定一个 epoll 实例,循环监听其 Channel
上的事件。
void EventLoop::loop() {
while (!quit_) {
int numEvents = epoll_wait(epollFd_, events, MAX_EVENTS, -1);
for (int i = 0; i < numEvents; ++i) {
Channel* channel = static_cast<Channel*>(events[i].data.ptr);
channel->handleEvent();
}
}
}
2. Channel
(事件通道)
每个 Channel 绑定一个 fd,以及对应的回调函数(读写事件)。
class Channel {
public:
using EventCallback = std::function<void()>;
void setReadCallback(const EventCallback& cb);
void handleEvent();
private:
int fd_;
EventCallback readCallback_;
};
3. TcpServer
(主服务器)
- 管理所有连接
- 使用
Acceptor
接收新连接 - 将连接派发给
EventLoopThreadPool
中的某个线程
class TcpServer {
public:
void start(); // 启动监听,进入主事件循环
private:
Acceptor acceptor_;
EventLoopThreadPool threadPool_;
std::map<int, TcpConnectionPtr> connections_;
};
4. TcpConnection
(连接类)
代表每个客户端连接,包括 socket 和绑定的 Channel
。
5. Acceptor
- 封装监听 socket
- 负责
accept
新连接并触发回调
class Acceptor {
public:
Acceptor(EventLoop* loop, int port);
void listen();
void setNewConnectionCallback(const NewConnCallback&);
};
6. ThreadPool
+ EventLoopThread
- 启动多个线程,每个线程运行一个
EventLoop
- 提供
getNextLoop()
方法轮询分配连接
🖥️ main.cpp 示例
int main() {
EventLoop mainLoop;
TcpServer server(&mainLoop, 8888);
server.start();
mainLoop.loop();
return 0;
}
🧪 功能验证
# 编译
g++ -std=c++17 -pthread *.cpp -o server
# 运行服务器
./server
# 另开终端模拟客户端连接
telnet 127.0.0.1 8888
🚀 项目亮点
- 模拟 Muduo 的 Thread-per-Loop 模式,线程安全地处理连接
- 使用现代 C++ (
std::function
,shared_ptr
, RAII) 提升代码质量 - 框架分层清晰,可扩展为 HTTP、WebSocket 服务框架
📚 后续可拓展点
- 支持定时器(如使用
timerfd
) - 支持连接超时清理
- 支持
std::future
异步任务投递 - 实现线程间消息队列
如果你需要完整代码文件或者想将该结构进一步封装成库式项目,可继续告诉我,我可以帮你逐个文件编写并解释其功能。
发表回复