代码仓库:https://gitee.com/tgwTTT/linux-learning-dai/tree/master/ThreadPool

上一篇文章带领大家学习了socket编程基础今天就带领大家实战演练一下,夜也深了,博主码完也要去休息了。
核心设计思路
1. 网络通信层设计
UDP协议选择理由:
- 实时性要求高:聊天系统对延迟敏感,UDP无连接特性更适合
- 广播功能天然支持:UDP天然支持一对多通信模式
- 资源消耗低:无需维护TCP连接状态,节省服务器资源
关键设计要点:
单线程事件循环:主线程专门负责消息接收,避免IO阻塞
异步处理机制:收到消息后立即交给线程池处理,不阻塞接收循环
地址信息封装:将sockaddr_in结构封装为友好的InetAddr对象
2. 消息路由架构
路由表管理策略:
- 自动发现机制:首次发送消息的用户自动加入在线列表
- 心跳检测:通过消息活跃度维持用户在线状态
- 优雅退出:支持”QUIT”命令的规范退出处理
3. 并发处理模型
线程池工作模式:
- 固定线程数:预先创建一定数量的工作线程
- 任务队列:使用线程安全队列缓冲待处理消息
- 条件变量同步:工作线程在无任务时自动休眠
资源管理策略:
连接无状态:UDP特性使得无需维护连接状态
内存池优化:可考虑使用对象池管理频繁创建的对象
流量控制:通过队列长度实现简单的背压控制
下面是一些核心代码,完整代码请参考代码仓库
核心架构:三层设计
1. 网络层 – 精简的UDP服务
// UDP服务器核心循环
void runServer() {
while (running) {
char buffer[1024];
sockaddr_in clientAddr;
socklen_t addrLen = sizeof(clientAddr);
// 接收消息
int received = recvfrom(sockfd, buffer, sizeof(buffer), 0,
(sockaddr*)&clientAddr, &addrLen);
if (received > 0) {
buffer[received] = '\0';
// 将消息交给处理线程
threadPool.enqueue([this, clientAddr, msg = std::string(buffer)] {
processMessage(clientAddr, msg);
});
}
}
}
2. 业务层 – 智能路由
// 消息处理核心
void processMessage(sockaddr_in clientAddr, const std::string& msg) {
// 自动注册新用户
if (!userExists(clientAddr)) {
addUser(clientAddr);
}
// 广播消息
std::string formattedMsg = formatMessage(clientAddr, msg);
broadcast(formattedMsg);
// 处理退出命令
if (msg == "QUIT") {
removeUser(clientAddr);
}
}
3. 并发层 – 高效线程池
// 线程池工作线程
void workerThread() {
while (running) {
std::function task;
{
std::unique_lock lock(queueMutex);
// 等待任务
condition.wait(lock, [this] {
return !taskQueue.empty() || !running;
});
if (!running) break;
task = std::move(taskQueue.front());
taskQueue.pop();
}
// 执行任务
task();
}
}
时间也不早了,如果有错误,欢迎在作者评论区留言,晚安!!!
评论
还没有任何评论,你来说两句吧!