Boost.MySQL v1.84保存连接后访问出现文件句柄无效错误
问题根源
你遇到的The file handle supplied is not valid [system:10009]错误,核心原因是连接依赖的IO上下文对象被提前销毁:
- 在
initialize函数中,boost::asio::io_context ctx和boost::asio::ssl::context ssl_ctx是局部变量,函数执行完成后这两个对象会被销毁 tcp_ssl_connection通过ctx.get_executor()绑定了io_context的执行器,同时持有ssl_context的引用,当这些上下文对象销毁后,连接底层的文件句柄和IO资源已经失效,后续访问自然会抛出无效句柄错误
修复方案
将io_context和ssl_context提升为类的成员变量,确保它们的生命周期和_connection一致。修改后的代码示例如下:
类成员声明
首先在类定义中添加这两个成员:
class DatabaseProcess { private: boost::asio::io_context _ctx; boost::asio::ssl::context _ssl_ctx{boost::asio::ssl::context::tls_client}; std::shared_ptr<boost::mysql::tcp_ssl_connection> _connection; std::atomic<bool> _is_initialized{false}; // 其他成员... };
修改initialize函数
调整initialize函数,使用类成员的上下文对象来创建和初始化连接:
void initialize(std::string host, int port, std::string user, std::string pass, std::string database) { try { // 初始化SSL上下文(按需配置,示例为测试环境配置) _ssl_ctx.set_default_verify_paths(); _ssl_ctx.set_verify_mode(boost::asio::ssl::verify_none); // 使用成员的io_context和ssl_context创建连接 _connection = std::make_shared<boost::mysql::tcp_ssl_connection>(_ctx.get_executor(), _ssl_ctx); boost::asio::ip::tcp::resolver resolver(_ctx.get_executor()); auto endpoints = resolver.resolve(host, std::to_string(port)); boost::mysql::handshake_params params(user, pass, database); // 同步连接,此时io_context无需额外run(同步接口会阻塞直到完成) _connection->connect(*endpoints.begin(), params); } catch (boost::mysql::error_with_diagnostics &error) { HLog(error) << error.what(); } bool value = false; _is_initialized.compare_exchange_strong(value, true); }
注意事项
- 如果后续使用Boost.MySQL的异步接口,需要保证
_ctx.run()被调用(可在单独线程运行,或集成到主线程事件循环) - SSL上下文的
verify_none仅适用于测试环境,生产环境建议开启证书验证并配置正确的证书路径 - 确保
_is_initialized初始值为false,避免未完成初始化就被访问
验证修复
修改后再调用test_database_connection函数,连接的底层资源会保持有效,不会再出现无效文件句柄的错误。
内容的提问来源于stack exchange,提问作者SagunKho
相关产品推荐
相关产品推荐

