🎬 个人主页:艾莉丝努力练剑
❄专栏传送门:《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录》 《Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享》
⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平
🎬 艾莉丝的简介:

文章目录
- 1 ~> ChatServer 启动与停止模块
-
- 1.1 业务背景与前置条件
- 1.2 头文件定义(类声明)
-
- 1.2.1 类成员说明
- 1.3 start () 服务启动接口实现
-
- 1.3.1 核心逻辑流程
- 1.4 stop () 服务停止接口实现
-
- 1.4.1 核心逻辑流程
- 1.5 isRunning () 状态查询接口实现
- 1.6 ChatServer 构造函数关键初始化逻辑
- 2 ~> 关键技术要点与坑点总结
-
- 2.1 为什么必须放到子线程执行 listen
- 2.2 为什么使用 std::atomic,不使用普通 bool
- 2.3 detach 线程注意事项
- 2.4 接口调用时序约束
- 3 ~> 面试核心考点
- 结尾

1 ~> ChatServer 启动与停止模块
基于 C++ + httplib 库实现 HTTP 聊天服务,解决服务启停、主线程阻塞、多线程并发状态安全问题
1.1 业务背景与前置条件
- 前置工作:模型配置完成,聊天 SDK 完成初始化;基于httplib::Server构建 HTTP 服务实例
- 需要实现 3 个核心接口:服务启动、服务停止、运行状态检测
- 核心痛点:httplib::Server::listen()为阻塞调用,直接在主线程调用会阻塞整个程序,必须将服务监听放置在独立子线程执行
- 并发风险:启停跨线程读写运行状态标记变量,普通 bool 会产生数据竞争,必须使用原子变量保证线程安全
1.2 头文件定义(类声明)
1.2.1 类成员说明
- 构造函数:接收服务器配置结构体ServerConfig
- 析构函数:资源回收
- 对外成员函数
- bool start():启动 HTTP 服务,子线程运行监听逻辑
- void stop():停止 HTTP 服务
- bool isRunning() const:获取服务当前运行状态
- 私有成员
- ServerConfig _config:保存传入的服务 IP、端口配置
- std::unique_ptr<httplib::Server> _chatServer:httplib 服务智能指针对象
- std::shared_ptr<ai_chat_sdk::ChatSDK> _chatSDK:聊天 SDK 智能指针
- std::atomic<bool> _isRunning{false}:原子布尔标记,标记服务运行状态,解决多线程读写竞争
#pragma once
#include <memory>
#include <atomic>
#include <httplib.h>
#include "server_config.h"
#include "ai_chat_sdk.h"
struct ServerConfig
{
std::string host;
uint16_t port;
};
namespace ai_chat_server
{
class ChatServer
{
public:
ChatServer(const ServerConfig& config);
~ChatServer();
bool start(); // 启动服务器
void stop(); // 停止服务器
bool isRunning() const; // 获取运行状态
private:
ServerConfig _config;
std::unique_ptr<httplib::Server> _chatServer = nullptr;
std::shared_ptr<ai_chat_sdk::ChatSDK> _chatSDK = nullptr;
std::atomic<bool> _isRunning{false}; // 原子变量,多线程安全标记运行状态
};
}
1.3 start () 服务启动接口实现
1.3.1 核心逻辑流程
注意:detach()只是分离线程,不代表 listen 监听一定成功;detach 之后主线程无法 join 回收该线程资源。listen 内部会处理端口绑定失败,错误日志会在子线程输出。
#include "ChatServer.h"
#include <thread>
#include "logger.h"
namespace ai_chat_server
{
bool ChatServer::start()
{
// 原子加载:检测服务是否已经处于运行状态
if (_isRunning.load())
{
ERR("ChatServer is running!!!");
return false;
}
// 创建子线程,将阻塞的listen监听放到子线程执行,避免阻塞主线程
std::thread serverThread([this]() -> void
{
// httplib阻塞监听,绑定配置中的IP与端口
_chatServer->listen(_config.host, _config.port);
INFO("ChatServer start on {}:{}", _config.host, _config.port);
});
// 线程分离,子线程独立运行生命周期,主线程不再管理该线程
serverThread.detach();
// 原子写:标记服务已经启动
_isRunning.store(true);
INFO("ChatServer start success!!!");
return true;
}
}
1.4 stop () 服务停止接口实现
1.4.1 核心逻辑流程
底层原理:httplib::Server::stop()会主动终止 listen 阻塞调用,退出子线程内部的监听循环;detach 分离后的子线程执行完 listen 退出后自动回收。
namespace ai_chat_server
{
void ChatServer::stop()
{
// 原子加载读取运行状态
if (!_isRunning.load())
{
ERR("ChatServer is not running!!!");
return;
}
// 调用httplib库接口停止服务
if (_chatServer)
{
_chatServer->stop();
}
// 原子写,更新运行标记为停止
_isRunning.store(false);
INFO("ChatServer stop success!!!");
}
}
1.5 isRunning () 状态查询接口实现
- 直接调用load()原子读操作返回内部状态,const 修饰保证不修改对象
namespace ai_chat_server
{
bool ChatServer::isRunning() const
{
return _isRunning.load();
}
}
1.6 ChatServer 构造函数关键初始化逻辑
namespace ai_chat_server
{
ChatServer::ChatServer(const ServerConfig& config):_config(config)
{
// 创建httplib服务实例
_chatServer = std::make_unique<httplib::Server>();
if (!_chatServer)
{
ERR("ChatServer init Failed!!!");
return;
}
// 此处完成ChatSDK初始化逻辑
}
}
2 ~> 关键技术要点与坑点总结
2.1 为什么必须放到子线程执行 listen
- httplib::Server::listen()是同步阻塞 API,调用后函数不会返回,直到调用 stop ()、发生异常出错
- 如果直接在主线程调用 listen,主线程被挂起,程序无法执行其他业务逻辑,无法调用 stop 完成关闭
2.2 为什么使用 std::atomic,不使用普通 bool
- start 在主线程修改_isRunning,子线程库内部也会间接访问,stop 也会修改;多线程同时读写普通 bool 变量会触发数据竞争,属于 C++ 未定义行为
- std::atomic<bool>提供原子读写:
- .load():原子读,获取变量值
- .store(val):原子写,写入变量值
- 禁止直接对原子变量使用=赋值,规范使用 load/store 接口
2.3 detach 线程注意事项
- detach()之后主线程不能 join 该线程,子线程运行结束后操作系统自动回收资源
- 风险点:对象提前析构,如果 ChatServer 对象被销毁,而子线程还在执行 lambda 内部逻辑,会发生野指针访问崩溃;业务层要保证对象生命周期大于服务子线程生命周期。
2.4 接口调用时序约束
3 ~> 面试核心考点
结尾
uu们,本文的内容到这里就全部结束了,艾莉丝在这里再次感谢您的阅读!
|
艾莉丝努力练剑
C/C++ & Linux 底层探索者 | 一个正在努力练剑的技术博主 👀 ❤️ ⭐ 💬 不要忘记给博主“一键四连”哦! “今日练剑达成!” “技术之路难免有困惑,但同行的人会让前进更有方向。” |
结语:希望对学习Linux相关内容的uu有所帮助,不要忘记给博主“一键四连”哦!
往期回顾:
【AI大模型接入SDK】ChatServer HTTP接口模块实现总览
🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡
૮₍ ˶ ˊ ᴥ ˋ˶₎ა






