【问题标题】:boost::asio::basic_waitable_timer custom clockboost::asio::basic_waitable_timer 自定义时钟
【发布时间】:2018-11-19 15:01:12
【问题描述】:

我想创建一个可以手动设置并与boost::asio::basic_waitable_timer一起使用的自定义时钟

我尝试了以下方法:

class my_clock {
public:
    using duration = std::chrono::nanoseconds;
    using time_point = std::chrono::time_point<std::chrono::system_clock>;
    static time_point now() {
       return n;
    }
    static void set_now(time_point now) {
        n = now;
    }
private:
    static time_point n;

};
my_clock::time_point my_clock::n = my_clock::time_point();

然后按如下方式使用:

boost::asio::io_context ctx;
auto now = std::chrono::system_clock::now();
my_clock::set_now(now);
auto next_expire = now + std::chrono::milliseconds(10);
boost::asio::basic_waitable_timer<my_clock> ctimer(ctx);
ctimer.expires_at(next_expire);

int count = 0;
ctimer.async_wait([&](const boost::asio::error_code& ec) {
    count++;
});
ctx.run_one();
// count == 0
my_clock::set_now(next_expire + std::chrono::seconds(1));
ctx.run();
// count == 1, except it's NOT

关于如何以这种方式将自定义时钟注入basic_waitiable_timer 有什么建议吗?

【问题讨论】:

    标签: c++ boost boost-asio chrono


    【解决方案1】:

    只要您的时钟满足TrivialClock 的要求,您就应该可以将它与basic_waitiable_timer 一起使用。 举几个例子:

    【讨论】:

      【解决方案2】:

      在@sergiopm 的回复的帮助下,以下是一个可行的解决方案:

      class my_clock {
      public:
          using duration = std::chrono::nanoseconds;
          using time_point = std::chrono::time_point<my_clock>;
          using rep = duration::rep;
          using period = duration::period;
          static constexpr bool is_steady = false;
      
          static time_point now() noexcept {
             return n;
          }
          static void set_now(time_point now) {
              n = now;
          }
      private:
          static time_point n;
      };
      

      然后您需要覆盖 waitable_timer 的等待特征,以便它在轮询 io 上下文时不会在挂钟上等待:

      struct wait_traits
      {
        static typename my_clock::duration to_wait_duration(
            const typename my_clock::duration& d)
        {
              return std::chrono::nanoseconds(0);
        }
      };
      

      然后进行如下练习:

      asio::io_context ctx;
      auto now = my_clock::time_point(my_clock::duration(10));
      my_clock::set_now(now);
      asio::basic_waitable_timer<my_clock, wait_traits> ctimer(ctx);
      auto next_expire = now + std::chrono::milliseconds(10);
      ctimer.expires_at(next_expire);
      ctimer.async_wait([&](const asio::error_code& ec) {
          future_period_count++;
          std::cout << "THIS HAPPENED" << std::endl;
      });
      ctx.poll_one();
      REQUIRE(future_period_count == 0);
      my_clock::set_now(next_expire + std::chrono::seconds(1));
      ctx.run_one();
      REQUIRE(future_period_count == 1);
      

      【讨论】:

        猜你喜欢
        • 2014-02-08
        • 1970-01-01
        • 1970-01-01
        • 2016-05-11
        • 2021-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多