【问题标题】:boost deadline_timer not waiting提升deadline_timer不等待
【发布时间】:2011-03-21 23:00:05
【问题描述】:

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

示例程序:

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

【问题讨论】:

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


    【解决方案1】:

    您将本地时间与系统时间混合在一起。 asio 将您的本地时间与您的本地时间进行比较的时间很可能是您希望设置截止日期的时间之后的几个小时,因此 wait 立即返回(取决于您居住的地方;同样的代码也可能等待几个小时)。为避免这一点混淆,绝对时间应从 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; 
    }
    

    在这种情况下你应该可以解决。

    【讨论】:

      【解决方案2】:

      您将异步方法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;
      }
      

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

      可能不相关:45 毫秒是一个很小的增量。根据我的经验,任何处理程序通过 Asio epoll reactor 队列的最短时间约为 30 毫秒,这在更高负载下可能会更长。虽然这在很大程度上取决于您的应用程序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-09
        相关资源
        最近更新 更多