我注意到以下代码启动了 2 个线程(Windows 8.1、MSVC 2013)。在 acceptor.accept()
等待约 10 秒后,它将产生 2 个额外的线程。如果进程空闲几分钟,就会减少到三个。
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
using namespace boost::asio;
int main(int argc, char** argv)
{
int test;
ssl::context ctx(ssl::context::tlsv12_server);
/* ctx settings */
io_service io_service;
ssl::stream<ip::tcp::socket> socket(io_service, ctx);
ip::tcp::acceptor acceptor(io_service, ip::tcp::endpoint(ip::tcp::v4(), 4433), false);
acceptor.accept(socket.lowest_layer());
socket.handshake(ssl::stream_base::server);
read(socket, buffer(&test, sizeof(test)));
boost::system::error_code error;
socket.shutdown(error);
if (error && error != boost::asio::error::eof) throw boost::system::system_error(error);
socket.lowest_layer().shutdown(ip::tcp::socket::shutdown_both);
socket.lowest_layer().close();
}
这种行为对我来说有点奇怪,我什至不使用单个异步操作、线程或其他东西。
我做了一些测试,似乎只有当我使用 SSL 套接字时才会出现问题。 这两个示例(包括阻塞和非阻塞)仅启动一个线程。
我也试过this “官方”异步 SSL 示例,但它会产生同样的问题。
是什么导致了这个问题?我可以消除这种行为吗?
最佳答案
您是否调试了线程(检查调用堆栈以查看正在运行的内容)。
无论如何,如果真正的异步不可用,Asio IO 服务可以使用模拟异步来实现它们的操作。真正的(操作系统级别)异步应该可用于常规文件、套接字、COM(串行)端口等。
我可以想象 Boost Asio SSL 实现使用这样一个后台线程来模拟一些与 SSL 协议(protocol)相关的有状态的东西。您可以查看文档以了解是否属于这种情况。¹
然而,所有的事情都是平等的,你已经拥有了
- 一些证据表明情况确实如此(除非您使用 SSL,否则不会出现额外的线程)
- 找出方法(当“神秘线程”出现时停止程序并检查它们的调用堆栈
¹ 在相关说明中,线程用于管理计时器,例如./detail/impl/win_iocp_io_service.ipp
更新 正如 OP 所发现的,这条线索恰到好处:
关于c++ - Boost.Asio SSL 神秘线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31502749/