tags:

views:

963

answers:

15

What is the simplest way to write a timer in C/C++?

Hi,

What is the simplest way to write a timer, say in C/C++? Previously I used a for loop and a do-while loop. I used the for loop as a counter and the do-while loop as a comparison for "end of time". The program worked as I wanted it to, but consumed too much system resources.

I'm looking for the simplest way to write a timer.

Thank you!

EDIT:

The program works on a set of servers both Linux and Windows, so it's a multiplatform environment. I dont want to use the unsleep or sleep function as I'm trying to write everything from scratch.

The nature of the program: The program counts power time and battery time on systems.

EDIT2:

OK, it seems that this caused some confusion so I'm going to try to explain what I have done so far. I've created a program that runs in the background and powers off the system if it's idle for a certain amount of time, it also checks for the battery life on a specific system and goes to stand by mode if the system has been running on battery for a while. I input the time manually so I need a timer. I want to write it from scratch as it's a part of a personal project I've been working on.

+1  A: 

use a sleep function.. and a function pointer

using sleep function doesnt consume processor time... You can use the function pointer to notify when the timer expired. if you dont need events you can simply use sleep/delay function

Edit do what smallduck has suggested. using macros for currectly calling the approperiate operating system call (if you want to avoid using boost)... using anything else then timer wont be accurate.

Umair Ahmed
I know about the sleep function, but I'm looking for a solution that doesn't include the sleep function.
Secko
You need to use the timer if you want accuracy (relatively).. as a for (etc) loop wont execute in same amount of time.
Umair Ahmed
@Umair Ahmed Hmm, you made me think!
Secko
+1  A: 

You didn't mention the environment you're building a timer in. For example, microcontrollers usually have a timer/counter unit that raise interrupts at some intervals by counting the clock cycles and you can just handle their interrupts.

Mehrdad Afshari
The program works on a set of server both Linux and Windows, so it's a multiplatform environment.
Secko
So you are running on an already existing OS which already has a timer. You aren't building one.
Mehrdad Afshari
@Mehrdad I'm not using the OS's timer.
Secko
@Secko why not? what sort of resolution do you want and why?
pjc50
@pjc50 I'm trying to build everything from scratch. The way I look at it is, you can't learn without trying.
Secko
+10  A: 

Your best bet is to use an operating system primitive that suspends the program for a given amount of time (like Sleep() in Windows). The environment where the program will run will most likely have some mechanism for doing this or similar thing. That's the only way to avoid polling and consuming CPU time.

sharptooth
Yup. You say you want to write everything from scratch. Hopefully this is for learning purposes only. But you've sorta reached the "end of the line". Aside from `time()` polls and a loop, the OS will provide you with `sleep()`ing methods, and the only way to 'scratch' some more would be to start delving into writing your own OS...
GMan
@Gman Nice comment!
Secko
@GMan If this was the answer, I would have accepted it.
Secko
A: 

If all you need is a code snippet that lets your program rest, a call to sleep is enough (if you're OK with second granularity).

Vatine
+5  A: 

If you just want your program to wait a certain amount of time, you can use:

  • Sleep (in Windows)
  • usleep (in Unix)
  • boost::this_thread::sleep (everywhere)

If you wish to process or display the time going up until elapsed, your approach of using a while() loop is fine, but you should add a small sleep (20ms, for example, but ultimately that depends on the precision you require) in the while loop, as not to hog the CPU.

small_duck
A: 

If you need to run multiple timers with a single thread then maintaining a hash table holding active timers is a very good method. You use the expiry time to form the hash key. Each timer tick you then search the hash table for timers which have expired.

Howard May
A: 
  void SimpleTimer(int timeinterval)
  {
       int starttime, currenttime, difference;
       starttime = time(null);

       do
       {
            currenttime = time(null); 
            difference = currenttime - starttime;
       }
       while (difference < timeinterval);
  }
No, no, no, no... It is just plain wrong AND the poster already says he has gone down that road.
kigurai
You should chill out. I was only trying to help and beside this one is without the For loop.
+1  A: 

You can call time() multiple times and compare the values.

#include <time.h>

int main ()
{
  time_t start_time;
  time_t current_time;

  start_time = time(NULL);
  current_time = time(NULL)

  while (current_time < start_time + TIMEOUT)
  {
  /* Do what you want while you're waiting for the timeout */
  current_time = time(NULL);
  }

 ...
}

The advantage over sleep() is that you can still execute code while you are waiting. For example... polling for an external stop signal, etc.

kjfletch
+3  A: 

There are two ways:

One. Write your own timer which wraps the platform specific command. And stick to using it. e.g.

void MySleep::Sleep(int milliSec)
{
#ifdef WIN32
   sleep(milliSec) ;
#else
#ifdef LINUX
   usleep(milliSec*1000); //microseconds
#endif
#endif
}

Two. Choose libraries and toolkits that support all your target platforms. Toolkits like Qt and boost can be used to cover up platform specific goo.

Both boost and Qt have timers with high functionality and are extensible. I recommend you look them up.

Fox
This solution does not account for SIGINT which would interrupt the usleep before the timeout passses.
Adrian Panasiuk
A: 

You could always play around with threads. One master thread could be scheduling tasks/jobs to be carried out at certain intervals. But then we are into the area of scheduling, which is something that the OS does. So as GMan said, you're suddenly in the realm of developing your own OS, or mimicing parts of the OS functionality.

Magnus Skog
A: 

Look at this article http://www.codeproject.com/KB/cpp/Low_Resolution_Timer.aspx

It may help.

luc
A: 

http://linux.die.net/man/2/alarm

Description:
alarm() arranges for a SIGALRM signal to be delivered to the process in seconds seconds.

and use cygwin on windows.

Adrian Panasiuk
A: 

it is not a trivial task because depending on your requirements it can be quite complex.

the problem with timers is that if you want a good timer you may need to move beyond c++(/c) into the realm of OS calls causing you to end up with a OS specific solution or use some library like boost to wrap it.

I mainly program in Windows so my advice come from that realm:

In windows you can of course use a timer(NULL) as some suggested however mostly when you are waiting you don't want to blog down the CPU with a loop. Using sleep is one way but instead I usually take the approach of using an object to wait for. Either the object signals or a timeout occurs. E.g. in order to wait for 10 seconds:

res = WaitForSingleObject( someobjecthandle, 10000 );

if the return value is timeout I know I waited 10s, otherwise the object signaled in some way and I didn't wait 10s. Now using that you can create an effective timer.

Another approach which is a bit more work is to create a separate timer thread (windows again) which periodically sends a message to your message loop.

A third approach is to create a thread that is the actual timer, you start the thread with an argument, the thread sleeps this time (ok i know u dont want to use that but u can use another MsgWaitForMultipleObjects function inside the thread to react if you want to kill the timer prematurely) and do a WaitForSingleObject on the handle of the thread, when it signals the time is up (or a timeout).

There are more ways to this but I hope I gave you at least some more ideas :)

Anders K.
+1  A: 

What you're already doing is the easiest.

It consumes too much CPU because it's going hard out doing your check (is timer expired?) or whatever.

To fix that put usleep(1) or whatever the OS equivalent of a very short sleep in that main loop and you'll have what you need.

Matt H
A: 

A lot of these answers include something known as "busy waiting." Checking the time over and over again in a while() loop is a bad idea 99% of the time.

I think you may want to step back and approach the problem a bit differently.

It sounds like you want a program to turn something off under a given set of conditions.

So you have a few options. You can "wake up" your background program every so often and check if conditions are met (using sleep / usleep, which are standard functions in all languages on all operating systems).

Or you can background the process indefinitely, until some type of event occurs. This would probably best be accomplished in C via signals or some type of wait function.

Its hard to tell exactly what you want, because its hard to tell how your standby / turn off conditions are met and how they are triggered.

You may want your battery monitor program to do some type of IPC or maybe write some type of dummy file to a known directory when it needs to standby. With IPC, you can use some type of wait() function that activates when a signal or IPC is sent to your background process. With the file method, you could sleep(), and check for that files existence every wake-up.

You could also easily use networking / sockets to do this as well. Listen on the loopback interface (127.0.0.1) and on a predefined port. Now wait until data comes in on that socket. When the battery monitor needs to standby, he sends a simple message via loopback to your new process. This will use effectively 0 cpu.

There are probably other ways as well, but I think that should give you a general idea.

James
Nice answer, but I'm not looking for alternatives. I just want to write my own timer.
Secko