提升deadline_timer不等

时间:2011-03-21 23:00:05

标签: c++ boost boost-asio deadline-timer

我尝试在这个简单的测试应用程序中使用boost deadline_timer,但遇到了一些麻烦。目标是使用expires_at()的{​​{1}}成员函数,每45毫秒触发一次计时器。 (我需要一个绝对时间,所以我不考虑deadline_timer。我现在也不关心漂移)。当我运行程序时,expires_from_now()不会等待45毫秒!然而,没有报告错误。我是否以某种方式错误地使用了库?

示例程序:

wait()

2 个答案:

答案 0 :(得分:7)

您正在将当地时间与系统时间混合。 asio比较当地时间的时间很可能是您希望截止日期设置的时间之后的几个小时,因此等待立即返回(取决于您居住的地方;同样的代码也可能等待几个小时)。为了避免这种混淆,绝对时间应该来自asio :: time_traits。

#include <boost/asio.hpp>
#include <boost/asio/time_traits.hpp>
#include <boost/thread.hpp> 
#include <boost/bind.hpp> 
#include <boost/date_time/posix_time/posix_time.hpp> 
#include <iostream> 
using namespace std;

typedef boost::asio::time_traits<boost::posix_time::ptime> time_traits_t;  
int main() {         
    boost::asio::io_service Service;         
    boost::shared_ptr<boost::thread> Thread;         
    boost::asio::io_service::work RunForever(Service);         
    Thread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&boost::asio::io_service::run, &Service)));
    boost::shared_ptr<boost::asio::deadline_timer> Timer(new boost::asio::deadline_timer(Service));          
    while(1)         
    {                 
        boost::posix_time::time_duration Duration;
        Duration = boost::posix_time::microseconds(45000);
        boost::posix_time::ptime Start = time_traits_t::now();
        boost::posix_time::ptime Deadline = Start + Duration;
        boost::system::error_code Error;
        size_t Result = Timer->expires_at(Deadline, Error);
        cout << Result << ' ' << Error << ' ';
        Timer->wait(Error);
        cout << Error << ' ';
        boost::posix_time::ptime End = boost::posix_time::microsec_clock::local_time();
        (cout << "Duration = " << (End - Start).total_milliseconds() << " milliseconds" << endl).flush();
     }         
    return 0; 
}

在这种情况下,这应该适合你。

答案 1 :(得分:4)

您正在将异步方法io_service::run与同步方法deadline_timer::wait混合使用。这不行。将deadline_timer::async_waitio_service::run一起使用,或跳过io_service::run并使用deadline_timer::wait。如果你去异步路由,你也不需要一个线程来调用io_service:run,一个线程就可以了。 Asio tutorial基本技能部分详细介绍了这两个概念。

void print(const boost::system::error_code& /*e*/)
{
  std::cout << "Hello, world!\n";
}

int main()
{
  boost::asio::io_service io;

  boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
  t.async_wait(print);
  io.run();

  return 0;
}

请注意,在调用io_service之前,您需要为run()提供一些服务。在此示例中,async_wait就是这项工作。

潜在无关:45ms是一个非常小的三角洲。根据我的经验,任何处理程序通过Asio epoll反应器队列的最短时间大约为30毫秒,在较高负载下这可能会相当长。虽然这在很大程度上取决于你的申请。