Gianluca Ghettini
Gianluca Ghettini

Reputation: 11658

Timeout in C++ using Boost datetime

How to implement a timeout while loop in C++ using boost::datetime?

something like:

#define TIMEOUT 12

while(some_boost_datetime_expression(TIMEOUT))
{
    do_something(); // do it until timeout expires
}

// timeout expired

Upvotes: 0

Views: 3640

Answers (4)

Vikas
Vikas

Reputation: 8948

This can easily be done with boost.Asio. Start a deadline_timer as one async process. It cancels the event loop when it expires. Keep posting your work to the same event loop till it is running. A working solution:

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

Upvotes: 0

Denis Ermolin
Denis Ermolin

Reputation: 5556

Use Boost::deadline_timer for timeouts. Constant check of value in loop is overkill for CPU.

Upvotes: 2

mkaes
mkaes

Reputation: 14119

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.

Upvotes: 1

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275800

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.)

Upvotes: 1

Related Questions