gpt4 book ai didi

c++ - Asio TCP 服务器在 DLL 卸载时崩溃

转载 作者:行者123 更新时间:2023-11-30 04:54:37 25 4
gpt4 key购买 nike

我正在使用独立的 Asio库托管一个简单的 TCP 服务器。代码位于一个动态库中,该库由我无法控制的主机应用程序加载。

库公开了一个OpenClose 函数,宿主应用程序应该在加载库之后/卸载库之前调用它们。
Open 函数中,我在单独的线程中运行 asio::io_service:

// start accepting connections
server.accept();

// start the asio service in a new thread
serviceThread = std::make_unique<std::thread>([this]() {
ioService.run();
});

Close函数中,我停止服务并加入线程:

// stop the asio service
ioService.stop();
serviceThread->join();

服务端的accept函数实现如下:

void Server::accept() {
acceptor.async_accept(socket, [this](std::error_code err) {
if (!err) {
std::lock_guard<std::mutex> lock(sessionsMutex);
sessions.emplace_back(new Session(*this, ioService, std::move(socket)));
}

accept();
});
}

asio::io_service 调用的其他函数的实现方式类似,即 lambda 函数绑定(bind) this 传递给 asio async 功能。

当主机应用程序根据需要调用 OpenClose 时,此代码工作正常。
但是,有时,宿主应用程序在卸载库之前没有调用Close 函数,从而导致错误的内存读取导致段错误:

Thread 14 Crashed:
0 com. 0x0000000121f1b14b asio::detail::scheduler::post_immediate_completion(asio::detail::scheduler_operation*, bool) + 27 (scheduler.ipp:281)
1 com. 0x0000000121f1f17c void asio::io_context::executor_type::post<asio::detail::work_dispatcher<myproject::Server::Session::write()::$_3>, std::__1::allocator<void> >(asio::detail::work_dispatcher<myproject::Server::Session::write()::$_3>&&, std::__1::allocator<void> const&) const + 124 (io_context.hpp:270)
2 com. 0x0000000121f1f027 asio::async_result<std::__1::decay<myproject::Server::Session::write()::$_3>::type, void ()>::return_type asio::post<asio::io_context::executor_type, myproject::Server::Session::write()::$_3>(asio::io_context::executor_type const&, myproject::Server::Session::write()::$_3&&, std::__1::enable_if<is_executor<asio::io_context::executor_type>::value, void>::type*) + 87 (post.hpp:58)
3 com. 0x0000000121f11cb2 asio::async_result<std::__1::decay<myproject::Server::Session::write()::$_3>::type, void ()>::return_type asio::post<asio::io_context, myproject::Server::Session::write()::$_3>(asio::io_context&, myproject::Server::Session::write()::$_3&&, std::__1::enable_if<is_convertible<asio::io_context&, asio::execution_context&>::value, void>::type*) + 50 (post.hpp:69)
[...]

我有哪些选择?是否有一种跨平台的方法来检测库的卸载(必须在 macOS 和 Windows 上工作),它允许我在任何情况下执行清理?
我可以修改我对 Asio 的使用来处理这种行为吗?

最佳答案

你最好的选择是只要它的代码在运行就保持库加载,例如LoadLibrary 启动线程时增加引用计数,FreeLibraryAndExitThread当工作线程死亡时。

主机应用程序可能会很不高兴,因为它喜欢库在被询问时没有卸载....但它是违反规则的,没有调用 Close()

而且不,甚至远程跨平台都没有。但是动态库的处理是特定于操作系统的。也许您可以找到一个专门用于处理动态库的跨平台包装器。

关于c++ - Asio TCP 服务器在 DLL 卸载时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53483003/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com