Boost.Asio SSL神秘线程

时间:2015-07-19 15:20:26

标签: c++ ssl boost boost-asio

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

是什么导致了这个问题?我可以消除这种行为吗?

1 个答案:

答案 0 :(得分:2)

您是否已调试线程(检查调用堆栈以查看正在运行的内容)。

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

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

然而,在所有条件相同的情况下,你已经拥有

  • 某些证据就是这种情况(除非您使用SSL,否则不会出现额外的线程)
  • 找出的方法(当“神秘线程”出现时停止程序并检查它们的调用堆栈

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

更新正如OP所发现的那样,这一领先优势非常明显:

enter image description here