【问题标题】:boost asio io_service::run() exits 'early' - or not?boost asio io_service::run() 退出“早” - 或不?
【发布时间】:2012-10-24 21:56:10
【问题描述】:

谁能告诉我boost::asioio_service::run()方法在什么条件下会返回?文档documentation for io_service::run() 似乎表明,只要有工作要做或要调度处理程序,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() 对“工作”的定义是什么?这是一个待处理的请求吗?为什么io_service::run() 在现有代码的请求和响应链中从不返回,但是当我尝试再次启动线程并启动新链时,它几乎在完成工作之前立即返回?

【问题讨论】:

    标签: c++ boost boost-asio


    【解决方案1】:

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

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

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

    【讨论】:

    • +1 OP 在后续运行之前很可能没有调用 reset
    • 这正是我没有做的。我添加了::reset() 电话,现在一切都很好。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多