【问题标题】:Deadline_timer not firing while calling async_connect in a loop在循环中调用 async_connect 时 Deadline_timer 未触发
【发布时间】:2020-06-25 16:39:20
【问题描述】:

尝试以与 boost 文档建议的方式类似的方式使用deadlinetimer: https://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/timeouts/blocking_tcp_client.cpp

代码: JNI 线程:

HttpClient client(io_service);
client.doAsyncOperation()
io_service.run()

HttpClient:

 doAsyncOperation(){
     timer_.expires_from_now(boost::posix_time::seconds(10));
     mSocket.async_connect( endpoint,
                       boost::bind(&HttpClient::handle_connect_async, this,
                                   boost::asio::placeholders::error)

}

void HttpClient::check_deadline(){
if (timer_.expires_at() <= deadline_timer::traits_type::now())
{
    mSocket.cancel();
}else{

   timer_.async_wait(boost::bind(&SchamanHttpClient::check_deadline, this));
}

}

更新: 修复:在单独的线程上运行 io_service

所以,在 JNI 线程内部:

 HttpClient client(io_service);
 client.doAsyncOperation()
 boost::thread t(boost::bind(&boost::asio::io_service::run,&io_service));
io_service.run();
t.join();

HttpClient:

void HttpClient::check_deadline(){
if (timer_.expires_at() <= deadline_timer::traits_type::now())
{
    mSocket.cancel();
    io_service.stop();
}else{

   timer_.async_wait(boost::bind(&SchamanHttpClient::check_deadline, this));
}

【问题讨论】:

    标签: boost java-native-interface boost-asio


    【解决方案1】:

    这些例子都不再是那样了。长期以来,存在更好的界面。一定要在最新版本的 boost 中查看这些示例:

    libs/asio/example/cpp03/timeouts/blocking_tcp_client.cpp
    libs/asio/example/cpp11/timeouts/blocking_tcp_client.cpp
    

    check_deadline() 不再被调用。怎么了?

    多种可能性:

    • 没有操作超时(10 秒很多)
    • 你没有运行 io_service(如果你不轮询/运行任务,什么都不会发生)
    • 计时器被破坏

    但是,我认为最可能让您感到困惑的是:当计时器到期(超时)时,它会将其设置为永不过期:

    void HttpClient::check_deadline() {
        if (timer_.expires_at() <= deadline_timer::traits_type::now()) {
            mSocket.cancel();
            timer_.expires_at(boost::posix_time::pos_infin);
        }
        timer_.async_wait(boost::bind(&HttpClient::check_deadline, this));
    }
    

    简而言之,所有这些“阻塞 IO 超时”背后的整个模式是您在每个操作之前设置超时

    【讨论】:

    • 谢谢你。我已经尝试过这个例子,但 async_connect 立即退出。 libs/asio/example/cpp11/timeouts/blocking_tcp_client.cpp
    • 当你甚至不说你用什么参数运行它时,很难说出任何事情。请注意,该演示适用于某些逐行文本协议服务器。
    • 我已经关闭了服务器,看看是否可以使用deadline_timer处理这种“无连接”的情况。所以在我运行的每个代码中,我只设置了一个 10 秒的计时器。使用您建议使用的代码示例,async_connect 以 EAGAIN 退出。在我使用过的所有其他示例中,它卡在 do_while
    • 我到了!关于 JNI 和 boost 之间的交互,我认为有些东西我没有掌握。我已经在一个线程中移动了“io_service.run”,现在计时器触发并调用了 check_deadline。我需要了解的最后一件事是如何停止 io_service(从 check_deadline 内部?)并加入。
    • 老实说,这听起来很奇怪(真的应该没什么区别)。此外,在这种情况下,首先使用异步连接会更好(你有 96% 在那里。我想只需将一些局部变量移动到成员)。
    猜你喜欢
    • 1970-01-01
    • 2017-12-07
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    相关资源
    最近更新 更多