Reputation:
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
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
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
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
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
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
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
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