[英]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_timer
的expires_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_wait
和io_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.