简体   繁体   中英

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

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.

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.

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.

There are two ways:

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

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.

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.

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.

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.

您没有提到您在其中构建计时器的环境。例如,微控制器通常有一个计时器/计数器单元,它通过计算时钟周期以一定的时间间隔引发中断,您可以只处理它们的中断。

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.

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 bog 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. Eg 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 (I know you don't want to use that but you 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 do this, but these are some starting points.

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.

如果您所需要的只是让您的程序休息的代码片段,那么调用 sleep 就足够了(如果您对第二个粒度没问题)。

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.

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.

 void SimpleTimer(int timeinterval) { int starttime, currenttime, difference; starttime = time(null); do { currenttime = time(null); difference = currenttime - starttime; } while (difference < timeinterval); }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM