ultraman
ultraman

Reputation:

Performing an operation at an interval

I want to perform the action at a certain timeout, like fire an event. I figured out how to do every n number of seconds, but not 1.5 seconds. Here is what I have. Please suggest how to handle my case:

void Publish()
{
    static  int local_time=time(NULL);

     int current_time = time (NULL);
     if((current_time+PUBLISH_TIMEOUT)>local_time)
      {
           fireEvent();
            local_time=current_time;
      } 
}

Upvotes: 1

Views: 386

Answers (7)

vottini
vottini

Reputation:

@puzzlecracker

Isn't CPU load a concern? Your routine keeps checking a condition an unnecessary number of times. I'd use usleep() when it misses:

...

 if(TIMEOUT < time_diff)
{
    cout<<TIMEOUT <<" seconds...\n";
    msec_base=now;

    return 1;
} else usleep(10);

...

This yield time for others processes, and doesn't give any penalty to yours code responsiveness.

An even better solution would be to use clock_nanosleep() with a different approach, like a threaded timer.

Upvotes: 0

Nick Van Brunt
Nick Van Brunt

Reputation: 15474

This returns the wall time since the application started in millisecs. It uses the machines clock so it is quite possible that changing the clock's time while the app is running will confuse it. In your case I would add a schedule time to my event object and fire when schedule time <= msec()

 clock_t msec() {
    static struct timeval msec_base;
    struct timeval now;

    long seconds, useconds; 
    if (!msec_base.tv_usec)
        gettimeofday(&msec_base, NULL);
    gettimeofday(&now, NULL);

    seconds  = now.tv_sec  - msec_base.tv_sec;
    useconds = now.tv_usec - msec_base.tv_usec;

    return ((seconds) * 1000 + useconds/1000.0);
}

Upvotes: 0

LB40
LB40

Reputation: 12331

I know this is not second based, but you can use the rdtsc register depending on your processor... More details here (for measuring time lapses in linux)

Upvotes: 0

poundifdef
poundifdef

Reputation: 19363

If this is C, why not use setitimer() and SIGALRM?

What setitimer() does it, at a certain interval (which you can specify up to the millisecond), it triggers the SIGALRM signal. Then, you can have your program set up so that it has a function which responds to that signal.

The alarm() function does the same thing as setitimer() - but alarm() only works for 1-second intervals (not 1.5 seconds, etc.) That said, this page gives a tutorial for how to handle the interrupt. You can save yourself a lot of time-calculating code using this method.

Upvotes: 0

Marenz
Marenz

Reputation: 2862

You can use boost::asio for that, see the documentation here:

http://think-async.com/Asio/boost_asio_1_4_1/doc/html/boost_asio/reference/deadline_timer.html

Upvotes: 0

ultraman
ultraman

Reputation:

A complete solution based on Nick's answer:

#include <sys/time.h>
#include <iostream>
#include <cstdlib>

using namespace std;

int TOTAL_PROCESSES;
double TIMEOUT;
int process()
{

    static struct timeval msec_base;
    struct timeval now;

    long seconds, useconds; 
    if (!msec_base.tv_usec)
        gettimeofday(&msec_base, NULL);

    gettimeofday(&now, NULL);

    seconds  = now.tv_sec  - msec_base.tv_sec;
    useconds = now.tv_usec - msec_base.tv_usec;

    double time_diff=seconds+ useconds/100000.0;

    if(TIMEOUT < time_diff)
    {
        cout<<TIMEOUT <<" seconds...\n";
        msec_base=now;

        return 1;
    }
     return 0;

}

int main(int argc, char** argv)
{
    if(argc < 3)
    {
        cout<<"Error: missing TIMOUT and total time to fire\n";
        return -1;

    }

    TIMEOUT       = atof(argv[1]);
    TIMES_TO_FIRE = atoi(argv[2]);

    cout << "INFO: TIMEOUT="<<TIMEOUT<<", TIMES_TO_FIRE ="<< TIMES_TO_FIRE <<endl; 


    int i=0;
    while (i< TIMES_TO_FIRE)
      i+=process();

    return 0;
}

Upvotes: 0

qrdl
qrdl

Reputation: 34968

gettimeofday() returns microseconds so you can use it instead of time() - see definition of struct timeval this function fills.

Check out man gettimeofday for details.

Upvotes: 1

Related Questions