steady_timer没有开火

时间:2016-06-07 11:08:16

标签: c++11 boost-asio

我需要能够在到期时间之后测试一个函数。在这个失败后,我写了一个小MCE来演示测试的基本要素。它返回时不触发处理程序。

取消注释下面的行'是否有过期的处理程序?'导致它回显到控制台,这意味着有一个未过期的处理程序。

根据documentation

  

处理程序将在以下时间调用:

     
      
  • 计时器已过期。
  •   
  • 计时器被取消,在这种情况下处理程序传递错误代码boost :: asio :: error :: operation_aborted。
  •   

所以我认为当该行被取消注释时,我至少应该让“处理程序”回显到屏幕上。

令人担忧的是,如果您在sleep_foryield行之后移动它,则仍有处理程序处于活动状态。

为什么我的计时器没有开火?

MCE:

#include <boost/asio.hpp>
#include <boost/asio/steady_timer.hpp>
#include <iostream>
#include <thread>

void handler(const boost::system::error_code& error)
{
    std::cout << "handler." << std::endl;
    if (!error)
    {
        std::cout << "Timer expired." << std::endl;
    }
}

int main(int argc, char* argv[]) 
{
    boost::asio::io_service io_service;

    // Construct a timer without setting an expiry time.
    boost::asio::steady_timer timer(io_service);

    // expire immediately
    timer.expires_from_now(std::chrono::seconds(0));

    // Wait for the timer to expire.
    timer.async_wait(handler);  

    // is there a handler to expire?
    // std::cout << "Expiry : " << timer.expires_from_now(std::chrono::seconds(1)) << std::endl;

    // added to allow the timer to expire
    std::this_thread::sleep_for(std::chrono::seconds(2));
    std::this_thread::yield();
}

1 个答案:

答案 0 :(得分:1)

<强>问题

您正在使用wait的异步变体而不调用io_service.run();

  

此调用是必需的,因为特定于操作系统的函数具有   接管控制权。请记住,它是I / O中的I / O服务   服务对象,它实现基于的异步操作   特定于操作系统的功能。

<强>解决方案

int main(int argc, char* argv[])
{
    boost::asio::io_service io_service;

    // Construct a timer without setting an expiry time.
    boost::asio::steady_timer timer(io_service);

    // expire immediately
    timer.expires_from_now(std::chrono::seconds(0));

    // Wait for the timer to expire.
    timer.async_wait(handler);

    io_service.run();
}