提升asio io_service :: run()退出'早' - 或不?

时间:2012-10-24 21:56:10

标签: c++ boost boost-asio

任何人都可以告诉我boost::asio的{​​{1}}方法会在什么条件下返回?文档documentation for io_service::run()似乎表明只要有工作或要处理的处理程序,io_service::run()就不会返回。

我问这个的原因是我们有一个传统的https客户端,它联系服务器并执行http POST。客户关注点的分离与我们想要的有点不同,所以我们改变了一些关于它的事情,但我们遇到了问题。

目前,客户端基本上有一个错误命名的run()调用,可以有效地驱动与服务器的整个协议对话。 connect()来电是通过创建connect()对象并在其上调用boost::asio::ip::tcp::resolver开始的。这将启动一个链接,在其中从asio回调中进行新的::async_resolve()调用。

asio

无论如何,这将继续通过协议,直到协议对话完成。从这里的代码可以看出,当void connect() { m_resolver.async_resolve( query, bind( &clientclass::resolve_callback, this ) ); thread = new boost::thread( bind( &boost::asio::io_service::run, m_io_service ) ); } void resolve_callback( error_code & e, resolver::iterator i ) { if (!e) { tcp::endpoint = *i; m_socket.lowest_layer().async_connect(endpoint, bind(&clientclass::connect_callback,this,_1,++i)); } } void connect_callback( error_code & e, resolve::iterator i ) { if (!e) { m_socket.lowest_layer().async_handshake(boost::asio::ssl::stream_base::client, bind(&clientclass::handshake_callback,this,_1,++i)); } } void handshake_callback( error_code &e ) { if (!e) { mesg = format_hello_message(); http_send( mesg, bind(&clientlass::hello_resp_handler,this,_1,_2) ); } } void http_send( stringstream & mesg, reply_handler handler ) { async_write(m_socket, m_request_buffer, bind(&clientclass::write_complete_callback,this,_1,handler)); } void write_comlete_callback( error_code &e, reply_handler handler ) { if (!e) { async_read_until(m_socket,m_reply_buffer,"\r\n\r\n", bind(&clientclass::handle_reply,this,handler)); } } ... 在主线程上运行时,所有后续回调和请求都会返回到connect()中创建的工作线程。这是“正常工作”的代码。

当我尝试打破此链并通过外部接口公开它时,它会停止工作。特别是,我在connect()对象之外进行了handle_handshake()调用。然后clientclass是接口的一部分(或由外部接口调用),它创建一个新的工作线程来调用io_service :: run()。即使http_send()已被调用,即使async_write()未返回,也会发生io_service :: run()退出。它没有错误地退出并声称没有派遣处理程序,但仍有“工作”要做?

所以我想知道的是write_complete_callback()对'工作'的定义是什么?这是待处理的请求吗?为什么io_service::run()在现有代码的请求和响应链中永远不会返回,但是当我尝试再次启动线程并启动一个新链时,它几乎在它完成工作之前立即返回? / p>

1 个答案:

答案 0 :(得分:3)

run()调用上下文中的工作定义是对该io_service对象的任何挂起的异步操作。这包括响应操作的处理程序的调用。因此,如果一个操作的处理程序启动另一个操作,则始终有可用的工作。

此外,还有一个io_service::work类可用于在io_service上创建工作,该工作在对象被销毁之前永远不会完成。

当单个链完成时,io_service已完成所有异步操作,并且在不启动新操作的情况下调用了所有处理程序,因此它返回。在您致电io_service::reset()之前,对run()的进一步调用将在不执行任何操作的情况下返回。