2012-10-24 65 views
1

有谁能告诉我在什么条件下boost::asioio_service::run()方法会返回?文档documentation for io_service::run()似乎表明,只要有工作要处理或处理程序要发送,run()将不会返回。boost asio io_service :: run()退出'早' - 或不?

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

现在,客户端基本上有一个错误的名称connect()调用,有效地驱动与服务器的整个协议对话。呼叫connect()通过创建一个boost::asio::ip::tcp::resolver对象并呼叫::async_resolve()开始。这启动了一个链,其中调用新的asio来自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()中创建的工作线程。这是'有效'的代码。

当我试图打破这个链并通过外部接口暴露它,它停止工作。特别是,我打电话给clientclass对象之外的电话handle_handshake()。然后http_send()是接口的一部分(或由外部接口调用),它创建一个新的工作线程来调用io_service :: run()。即使async_write()已被调用,即使write_complete_callback()未返回,io_service :: run()也会退出。它没有错误地退出并声称没有派遣人员,但仍有“工作要做”?

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

回答

3

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

此外,还有一个io_service::work类,可用于在io_service上创建工作,该工作从未完成,直到该对象被销毁。

当单链完成时,io_service已完成所有异步操作,并且所有处理程序的调用都未启动新操作,因此它将返回。在您拨打io_service::reset()之前,在不执行任何操作的情况下,将返回到run()的更多呼叫。

+0

+1在后续运行之前,OP很可能不会调用重置 – Ralf

+0

这完全是我没有做的事情。我加了':: reset()'调用,现在一切都很好。谢谢! –

相关问题