调用thread.interrupt()触发段错误:Boost Asio C++技术问题
问题分析与修复方案
核心崩溃原因
- 未初始化的线程指针:
startAccept中user_thread是未初始化的裸指针,先创建user usr(&socket, user_thread)时,user类的thread_成员被赋值为野指针。后续connection函数调用thread_->interrupt(),直接访问野指针触发段错误。 - 局部对象生命周期失效:
tcp::socket socket是startAccept循环内的局部变量,循环迭代结束后socket会被销毁,user类中保存的socket_指针变为悬空指针。user usr同样是循环内的局部对象,线程绑定的&usr在循环结束后指向已销毁的对象,线程后续访问会触发未定义行为。
- 线程管理逻辑混乱:用裸指针管理
boost::thread易引发内存泄漏,且刚启动线程就中断自身的设计无意义。
修复后的代码
#include <boost/asio.hpp> #include <boost/thread.hpp> #include <iostream> #include <memory> #include <vector> using namespace boost::asio; using tcp = boost::asio::ip::tcp; class user { private: std::string name_; std::unique_ptr<tcp::socket> socket_; boost::thread thread_; public: user(tcp::socket socket) : socket_(std::make_unique<tcp::socket>(std::move(socket))) { thread_ = boost::thread(&user::connection, this); } ~user() { if (thread_.joinable()) { thread_.interrupt(); thread_.join(); } } void connection() { try { while (true) { std::cout << "123" << std::endl; // 可在此添加实际的socket读写逻辑 boost::this_thread::sleep_for(boost::chrono::seconds(1)); } } catch (const boost::thread_interrupted&) { std::cout << "线程已中断" << std::endl; } } }; class server { private: boost::asio::io_context io_context_; tcp::acceptor acceptor_; std::vector<std::unique_ptr<user>> users_; public: server() : acceptor_(io_context_, tcp::endpoint(ip::address::from_string("127.0.0.1"), 3030)) {} void startAccept() { while (true) { tcp::socket socket(io_context_); acceptor_.accept(socket); users_.emplace_back(std::make_unique<user>(std::move(socket))); } } }; int main() { try { server serv; serv.startAccept(); } catch (const std::exception& e) { std::cerr << "服务器异常: " << e.what() << std::endl; } return 0; }
关键修复点说明
- 消除悬空指针:用
std::unique_ptr管理socket和user对象,通过移动语义传递socket,确保资源生命周期匹配。 - 正确初始化线程:在
user构造函数内直接创建线程并绑定当前对象,避免传递未初始化指针。 - 规范线程生命周期:
user析构时中断并等待线程结束,防止线程访问已销毁对象;用容器保存user智能指针,延长其生命周期至线程运行结束。 - 优化中断逻辑:线程内部捕获中断异常,优雅处理终止;添加延迟避免无限循环占用CPU。
内容的提问来源于stack exchange,提问作者muerewaa
相关产品推荐
相关产品推荐

