【问题标题】:boost asio service returning too soonboost asio 服务返回得太早
【发布时间】:2018-11-22 01:34:03
【问题描述】:

一直在尝试解决我面临的关于 io_service 对象的问题。有问题的代码:

    void connect_handler(const error_code &ec,iterator iterator){
        cout<<"Connect handler"<<endl;
    }

    void resolver_handler(const error_code &ec,iterator iterator,boost::asio::io_service &io){
        cout<<"Resolver handler..."<<endl;
        boost::asio::ip::tcp::socket socket(io);
        boost::asio::async_connect(socket,iterator,&connect_handler);
    }

    int main(){
        boost::asio::io_service io;
        resolver resolver(io);
        resolver::query query("example.com","http");
        resolver.async_resolve(query,boost::bind(resolver_handler,boost::asio::placeholders::error,boost::asio::placeholders::iterator,boost::ref(io)));
        cout<<io.run()<<endl;

        return 0;
    }

在另一个简单的例子中尝试了同样的事情,一切都按预期运行:

void printTwo(const error_code& ec,boost::asio::deadline_timer &timer,boost::asio::io_service &io){
    cout<<"print two"<<endl;
}

void printOne(const error_code& ec,boost::asio::deadline_timer &timer,boost::asio::io_service &io){
    cout<<"print one"<<endl;
    timer.async_wait(boost::bind(printTwo,boost::asio::placeholders::error,boost::ref(timer),boost::ref(io)));
}

int main(int argc, char** argv) {
    boost::asio::io_service io;
    boost::asio::deadline_timer timer(io,boost::posix_time::seconds(3));
    timer.async_wait(boost::bind(printOne,boost::asio::placeholders::error,boost::ref(timer),boost::ref(io)));
    cout<<io.run()<<endl;
    return 0;
}

我的假设是服务对象会阻塞,直到所有工作完成;调用 run 函数的线程也是调用处理函数的线程。那么,为什么第二个代码块按预期工作,而不是第一个?提前致谢。

【问题讨论】:

  • 您的套接字超出范围。
  • 我没有完全阅读您的问题,但我认为您应该查看boost.org/doc/libs/1_57_0/doc/html/boost_asio/reference/… 如果 io_service 无法正常工作,它将从该调用返回。通过将其放入 io_service 工作队列中,它只会呆在那里什么都不做,让 io_service 认为它需要继续运行。
  • 我假设io.run() 的返回速度太快了,还不是很清楚。
  • 你的套接字超出了范围。 @tkausl 是对的。
  • 在你的第二个例子中,deadline_timer 是保持io_service 活着的东西。三秒钟内,有“工作要做”,当这三秒钟到期(或计时器被重置)时,工作就“完成”了。

标签: c++ asynchronous boost service asio


【解决方案1】:

你的程序中的io.run() 将在io_service 认为它完成了它必须做的工作后立即返回。这可能发生在 操作之间,或者可能在调用最后一个异步回调时发生(我不完全确定)。

使用work object 通知io_service 继续运行,当您重置该工作对象时,io_servicerun() 调用应在执行完任何待处理操作后返回。

基本用法是这样的:

boost::asio::io_service io_service;
boost::asio::io_service::work work(io_service);
// ...
io_service.run(); // Blocks here

通常在另一个线程中,或者可能在其中一个异步回调中,您可以这样做:

work.reset();

一段时间后,run() 将返回。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-02
    • 1970-01-01
    • 2018-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多