如何使用 boost::datetime 在 C++ 中实现超时 while 循环?
就像是:
#define TIMEOUT 12
while(some_boost_datetime_expression(TIMEOUT))
{
do_something(); // do it until timeout expires
}
// timeout expired
使用Boost::deadline_timer超时。不断检查循环中的值对 CPU 来说是多余的。
You'll first want to mark the time you start, then calculate the difference between the current time and the time you started. No built-in boost datetime expression will work exactly like you describe. In boost datetime terminology: http://www.boost.org/doc/libs/1_51_0/doc/html/date_time.html the duration of your timeout is a "time duration", and the point you start is a "time point".
Suppose you want to be accurate to within a second, and have a 4 minute 2 second interval.
using namespace boost::posix_time;
ptime start = second_clock::local_time();
gives you a time point to start your timing
ptime end = start + minutes(4)+seconds(2);
gives you a point in time 4 minutes and 2 seconds from now.
And then
( second_clock::local_time() < end )
is true if and only if the current time is before the end time.
(Disclaimer: this is not based off actually writing any boost datetime code before, but just reading the docs and example code over at the boost website.)
You can just check the time difference:
boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
while((boost::posix_time::microsec_clock::local_time() - now) < boost::posix_time::milliseconds(TIMEOUT ) )
{
// do something
}
But instead of doing something like that you might rethink your design.
这可以通过boost.Asio轻松完成。作为一个异步进程启动一个deadline_timer 。它在事件循环到期时取消事件循环。继续将您的工作发布到同一个事件循环,直到它运行为止。一个可行的解决方案:
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
class timed_job
{
public:
timed_job( int timeout ) :
timer_( io_service_, boost::posix_time::seconds( timeout ) ) // Deadline timer
{
}
void start()
{
// Start timer
timer_.async_wait
(
boost::bind
(
&timed_job::stop, this
)
);
// Post your work
io_service_.post
(
boost::bind
(
&timed_job::do_work, this
)
);
io_service_.run();
std::cout << "stopped." << std::endl;
}
private:
void stop()
{
std::cout << "call stop..." << std::endl;
io_service_.stop();
}
void do_work ()
{
std::cout << "running..." << std::endl;
// Keep posting the work.
io_service_.post
(
boost::bind
(
&timed_job::do_work, this
)
);
}
private:
boost::asio::io_service io_service_;
boost::asio::deadline_timer timer_;
};
int main()
{
timed_job job( 5 );
job.start();
return 0;
}