2015-07-19 124 views
1

我注意到下面的代碼啓動了2個線程(Windows 8.1,MSVC 2013)。在等待acceptor.accept()約10秒後,它會產生2個額外的線程。如果進程閒置幾分鐘,則會減少到三分鐘。Boost.Asio SSL mystic threads

#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的例子,但它產生了同樣的問題。


什麼原因導致此問題?我能消除這種行爲嗎?

回答

2

您是否調試過線程(檢查調用堆棧以查看正在運行的內容)。

無論如何,如果真正的異步不可用,Asio IO服務可以使用模擬異步實現其操作。對於常規文件,套接字,COM(串行)端口等應該可以使用真(OS級別)異步。

我可以想象,Boost Asio SSL實現使用這樣的後臺線程來模擬一些與SSL協議相關的有狀態事物。你可以看看文件,看看這是否是case.¹

然而,所有的事情都是平等的,你已經有

  • 一些證據是這種情況(額外的線程不會出現,除非你「再利用SSL)
  • 手段找出(只是停止程序時,‘神祕線’的出現並檢查調用堆棧他們

¹在一個相關的注意,線程用於管理例如./detail/impl/win_iocp_io_service.ipp

更新由於OP發現,這種領先優勢被準確點注:

enter image description here

+0

謝謝,你是絕對正確的! https://i.imgur.com/VecbGVV.png – Anno

+0

@Anno Woot!該截圖說明了數量,我將其添加到答案中。 – sehe