Boost.Asio SSL 神秘线程

Boost.Asio SSL mystic threads

我注意到以下代码启动了 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 "official" 异步 SSL 示例,但它产生了同样的问题。


导致此问题的原因是什么?我可以消除这种行为吗?

您是否调试了线程(检查调用堆栈以查看 运行)。

无论如何,如果真正的异步不可用,Asio IO 服务可以使用模拟异步来实现它们的操作。 True(OS 级别)异步应该可用于常规文件、套接字、COM(串行)端口等。

我可以想象 Boost Asio SSL 实现使用这样一个后台线程来模拟一些与 SSL 协议相关的有状态的东西。您可以查看文档以了解是否属于这种情况。¹

然而,一切平等你已经拥有

  • 一些证据表明情况确实如此(除非您使用 SSL,否则不会出现额外的线程)
  • 找出方法(当 "mystic threads" 出现时停止程序并检查它们的调用堆栈

¹ 在相关说明中,线程用于管理计时器,例如./detail/impl/win_iocp_io_service.ipp

更新 正如 OP 所发现的,这条线索恰到好处: