简体   繁体   English

在 C/C++ 中编写计时器的最简单方法是什么?

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

What is the simplest way to write a timer in C/C++?在 C/C++ 中编写计时器的最简单方法是什么?

Hi,你好,

What is the simplest way to write a timer, say in C/C++?用 C/C++ 说,编写计时器的最简单方法是什么? Previously I used a for loop and a do-while loop.以前我使用了 for 循环和 do-while 循环。 I used the for loop as a counter and the do-while loop as a comparison for "end of time".我使用 for 循环作为计数器,使用 do-while 循环作为“时间结束”的比较。 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.该程序适用于 Linux 和 Windows 的一组服务器,因此它是一个多平台环境。 I dont want to use the unsleep or sleep function as I'm trying to write everything from scratch.我不想使用 unsleep 或 sleep 功能,因为我试图从头开始编写所有内容。

The nature of the program: The program counts power time and battery time on systems.程序的性质:该程序计算系统上的电源时间和电池时间。

EDIT2:编辑2:

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).最好的办法是使用操作系统原语,在给定的时间内暂停程序(如 Windows 中的 Sleep())。 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.这是避免轮询和消耗 CPU 时间的唯一方法。

If you just want your program to wait a certain amount of time, you can use:如果你只是想让你的程序等待一段时间,你可以使用:

  • Sleep (in Windows)睡眠(在 Windows 中)
  • usleep (in Unix) usleep(在 Unix 中)
  • boost::this_thread::sleep (everywhere) boost::this_thread::sleep(无处不在)

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.如果您希望处理或显示一直到过去的时间,您使用 while() 循环的方法很好,但您应该在while 循环,以免占用 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. Qt 和 boost 等工具包可用于掩盖特定于平台的 goo。

Both boost and Qt have timers with high functionality and are extensible. boost 和 Qt 都有功能强大且可扩展的定时器。 I recommend you look them up.我建议你查查它们。

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

Description:描述:
alarm() arranges for a SIGALRM signal to be delivered to the process in seconds seconds. alarm() 安排在seconds秒钟内将 SIGALRM 信号传递给进程。

and use cygwin on windows.并在 Windows 上使用 cygwin。

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.它消耗了太多的 CPU,因为它很难进行检查(计时器是否已过期?)或其他什么。

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.为了解决这个问题,在主循环中放入 usleep(1) 或任何相当于一个非常短的睡眠的操作系统,你就会得到你需要的东西。

use a sleep function.. and a function pointer使用 sleep 函数.. 和函数指针

using sleep function doesnt consume processor time... You can use the function pointer to notify when the timer expired.使用 sleep 函数不会消耗处理器时间......您可以使用函数指针来通知计时器何时到期。 if you dont need events you can simply use sleep/delay function如果您不需要事件,您可以简单地使用睡眠/延迟功能

Edit do what smallduck has suggested.编辑按照 smallduck 的建议进行操作。 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.使用宏当前调用适当的操作系统调用(如果您想避免使用 boost)...使用其他任何东西,那么计时器将不准确。

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

You can call time() multiple times and compare the values.您可以多次调用 time() 并比较值。

#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.与 sleep() 相比的优势在于您仍然可以在等待时执行代码。 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.计时器的问题在于,如果您想要一个好的计时器,您可能需要超越 C++/C 进入操作系统调用领域,这导致您最终得到特定于操作系统的解决方案或使用诸如 boost 之类的库来包装它。

I mainly program in Windows so my advice come from that realm:我主要在 Windows 中编程,所以我的建议来自该领域:

In Windows you can of course use a timer(NULL) as some suggested;在 Windows 中,您当然可以使用一些建议的timer(NULL) however mostly when you are waiting you don't want to bog down the CPU with a loop.然而,大多数情况下,当你在等待时,你不想让 CPU 陷入循环。 Using sleep is one way but instead I usually take the approach of using an object to wait for.使用 sleep 是一种方法,但我通常采用使用对象等待的方法。 Either the object signals or a timeout occurs.对象发出信号或发生超时。 Eg in order to wait for 10 seconds:例如为了等待 10 秒:

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.如果返回值是超时,我知道我等了 10 秒,否则对象以某种方式发出信号,我没有等 10 秒。 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.另一种需要更多工作的方法是创建一个单独的计时器线程(再次是 Windows),它会定期向您的消息循环发送消息。

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).第三种方法是创建一个作为实际计时器的线程,你用一个参数启动线程,这次线程休眠(我知道你不想使用它,但你可以在线程内使用另一个 MsgWaitForMultipleObjects 函数来做出反应如果您想提前终止计时器)并在线程的句柄上执行 WaitForSingleObject ,当它发出信号时间已到(或超时)时。

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.在 99% 的情况下,在 while() 循环中一遍又一遍地检查时间是个坏主意。

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).您可以每隔一段时间“唤醒”您的后台程序并检查是否满足条件(使用 sleep/usleep,这是所有操作系统上所有语言的标准功能)。

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.这可能最好通过信号或某种类型的等待函数在 C 中完成。

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.您可能希望您的电池监视器程序执行某种类型的 IPC,或者在需要待机时将某种类型的虚拟文件写入已知目录。 With IPC, you can use some type of wait() function that activates when a signal or IPC is sent to your background process.使用 IPC,您可以使用某种类型的 wait() 函数,该函数在将信号或 IPC 发送到后台进程时激活。 With the file method, you could sleep(), and check for that files existence every wake-up.使用 file 方法,您可以 sleep(),并在每次唤醒时检查该文件是否存在。

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.侦听环回接口 (127.0.0.1) 和预定义端口。 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.这将有效地使用 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.因此,正如 GMan 所说,您突然进入了开发自己的操作系统或模仿部分操作系统功能的领域。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C ++:在Windows上使用C ++读写BMP文件的最简单方法是什么? - C++: What's the simplest way to read and write BMP files using C++ on Windows? 编写要在Python中使用的并行C / C ++模块的最简单方法 - Simplest way to to write parallel C/C++ modules to be used in Python 在C ++中编写可移植动态可加载库的最简单方法是什么? - What's the simplest way to write portable dynamically loadable libraries in C++? 创建1个元素集的最佳\\最简单\\最快的方法是什么? (C ++) - What is the best\simplest\fastest way to create set of 1 element? (C++) 在c ++中将const char []转换为字符串的最简单方法是什么? - What is the simplest way to convert a const char[] to a string in c++ 在C ++中创建编辑框的最简单方法是什么 - what is the simplest way to create edit box in c++ 在 C++ 中测试一个数字是否是 2 的幂的最简单方法是什么? - What's the simplest way to test whether a number is a power of 2 in C++? 通过C ++代码使用WEKA最简单的方法是什么? - What is the simplest way to use WEKA through C++ code? 什么是在linux上c ++ / Qt中解雇和忘记线程的最简单方法? - What is the simplest way to fire and forget a thread in c++ / Qt on linux? 在C ++中动态创建和调用类方法的最简单方法是什么? - What is the simplest way to create and call dynamically a class method in C++?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM