views:

226

answers:

7

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;
      } 
}
+1  A: 

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.

qrdl
If you were to put this function on it's own thread and want to add a pause, gettimeday() uses the same type (struct timeval) that a select() call does. Depending on your circumstances, a select() could replace any time queries altogether.
Jamie
@Jamie I agree, but OP didn't ask for pause - if s/he did I'd rather suggest usleep() or even nanosleep(), because nano version is POSIX.
qrdl
A: 

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);
}
Nick
After a few modification, I made this to work, particularly you don't need to multiply seconds by 1000, and you have to delete useconds by 10,000.0Thanks.
you may want to have a look at CLOCKS_PER_SEC http://www.cplusplus.com/reference/clibrary/ctime/CLOCKS_PER_SEC/ for solving those type of issues.
Nick
A: 

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;
}
A: 

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

Marenz
I don't think you can, as I need a non-blocking to NEVER block, but skip execution until the timeout is exceeded.
A: 

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.

rascher
this won't work, as I only want to make a call when information is available and timeout has expired.
Well, ways to make that work might be: Your timer code would need to check to see if information is available at the time SIGALRM is set. Or do that with a combination of alarm cancellations.
rascher
if you want fractions of seconds you can use nanosleep()
Nathan Fellman
A: 

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)

LB
A: 

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

I can't block even though I cannot publish. My application is single threaded and does a lot of commutation, results of which it publishes at certain interval. Computing never stops.