简体   繁体   English

提升deadline_timer不等

[英]boost deadline_timer not waiting

I tried using the boost deadline_timer in this simple test application, but had some trouble. 我尝试在这个简单的测试应用程序中使用boost deadline_timer,但遇到了一些麻烦。 The goal is for the timer to trigger every 45 milliseconds using the expires_at() member function of the deadline_timer . 目标是使用deadline_timerexpires_at()成员函数每45毫秒触发一次计时器。 (I need an absolute time, so I'm not considering expires_from_now() . I am also not concerned about drift at the moment). (我需要一个绝对时间,所以我不考虑expires_from_now() 。我现在也不关心漂移)。 When I run the program, wait() does not wait for 45 ms! 当我运行程序时, wait()不会等待45毫秒! Yet, no errors are reported. 然而,没有报告错误。 Am I using the library incorrectly somehow? 我是否以某种方式错误地使用了库?

Sample program: 示例程序:

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

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 = boost::posix_time::microsec_clock::local_time();
                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;
}

You are mixing local time with system time. 您将本地时间与系统时间混合在一起。 The time that asio is comparing your local time to is most likely some number of hours after the time that you want your deadline set to so wait returns immediately (depending on where you live; this same code could wait for several hours as well). asio比较当地时间的时间很可能是您希望截止日期设置的时间之后的几个小时,因此等待立即返回(取决于您居住的地方;同样的代码也可能等待几个小时)。 To avoid this point of confusion, absolute times should be derived from asio::time_traits. 为了避免这一点混淆,绝对时间应该来自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; 
}

That should work out for you in this case. 在这种情况下,这应该适合你。

You are mixing asynchronous methods io_service::run with synchronous methods deadline_timer::wait . 您正在使用同步方法deadline_timer::wait混合异步方法io_service::run This will not work. 这不行。 Either use deadline_timer::async_wait with io_service::run , or skip the io_service::run and just use deadline_timer::wait . 使用deadline_timer::async_waitio_service::run ,或者跳过io_service::run并使用deadline_timer::wait You also don't need a thread to invoke io_service:run if you go the asynchronous route, one thread will do just fine. 你也不需要一个线程来调用io_service:run如果你去异步路由就运行,一个线程就可以了。 Both concepts are explained in detail in the Basic Skills section of the Asio tutorial . 这两个概念在Asio教程Basic Skills部分中有详细解释。

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;
}

Note you will need to give some work for your io_service to service prior to invoking run() . 请注意,在调用run()之前,您需要为io_service提供一些服务。 In this example, async_wait is that work. 在这个例子中, async_wait就是这样。

Potentially unrelated: 45ms is quite a small delta. 潜在无关:45ms是一个相当小的三角洲。 In my experience the smallest time for any handler to make it through the Asio epoll reactor queue is around 30 ms, this can be considerably longer at higher loads. 根据我的经验,任何处理程序通过Asio epoll反应器队列的最短时间大约为30毫秒,在较高负载下这可能会相当长。 Though it all largely depends on your application. 虽然这在很大程度上取决于您的应用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM