c++ - boost asio io_service::run() 是否退出 'early'?

标签 c++ boost boost-asio

谁能告诉我 boost::asioio_service::run() 方法在什么条件下会返回?文档 documentation for io_service::run()似乎表明只要有工作要做或要分派(dispatch)处理程序,run() 就不会返回。

我问这个问题的原因是我们有一个旧的 https 客户端,它联系服务器并执行 http POST。客户端中的关注点分离与我们想要的有点不同,因此我们正在更改一些内容,但我们遇到了问题。

现在,客户端基本上有一个命名错误的 connect() 调用,该调用有效地驱动与服务器的整个协议(protocol)对话。 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));
    }
}
...

无论如何,这将通过协议(protocol)继续进行,直到协议(protocol)对话完成。从这里的代码中您可以看到,当 connect() 在主线程上运行时,所有后续回调和请求都会返回到 connect() 中创建的工作线程上。这是“工作”代码。

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

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

最佳答案

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

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

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

关于c++ - boost asio io_service::run() 是否退出 'early'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13058430/

相关文章:

c# - 在 IIS7 中从 ASP.NET 调用非托管代码

c++ - 是否可以安全地假设 64 位指针中的 16 位高位(2 位对我来说足够)未设置?

C++ lambda自传递异常

c++ - boost asio 服务队列深度和策略

c++ - 对象的共享所有权是糟糕设计的标志吗?

c++ - 忽略 C++ 中模板类的重复显式实例化

c++ - boost 绑定(bind)模板错误

c++ - boost 文件映射性能

c++ - 代码中的随机错误

c++ - 我可以使用 boost::bind 来存储不相关的对象吗?