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

时间:2009-07-08 10:05:03

标签: c++ c

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

您好,

编写计时器最简单的方法是什么,比如在C / C ++中?以前我使用了for循环和do-while循环。我使用for循环作为计数器,使用do-while循环作为“结束时间”的比较。该程序按照我的意愿工作,但消耗了太多的系统资源。

我正在寻找编写计时器的最简单方法。

谢谢!

编辑:

该程序适用于Linux和Windows的一组服务器,因此它是一个多平台环境。我不想使用睡眠或睡眠功能,因为我正试图从头开始编写所有东西。

程序的性质:程序计算系统上的电源时间和电池时间。

EDIT2:

好吧,这似乎引起了一些混乱,所以我将试着解释到目前为止我做了什么。我已经创建了一个在后台运行的程序,如果它在一段时间内处于空闲状态,它会关闭系统电源,它还会检查特定系统上的电池寿命,如果系统一直在运行,则会进入待机模式电池一段时间。我手动输入时间,所以我需要一个计时器。我想从头开始编写它,因为它是我一直在努力的个人项目的一部分。

14 个答案:

答案 0 :(得分:9)

最好的办法是使用一个操作系统原语,在一段时间内暂停程序(如Windows中的Sleep())。程序运行的环境很可能会有一些机制来执行此操作或类似操作。这是避免轮询和消耗CPU时间的唯一方法。

答案 1 :(得分:5)

如果您只是希望程序等待一段时间,可以使用:

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

如果您希望处理或显示直到过去的时间,您使用while()循环的方法很好,但您应该添加一个小睡眠(例如,20ms,但最终取决于您的精度在while循环中,不要占用CPU。

答案 2 :(得分:3)

有两种方法:

一。编写自己的计时器,包装特定于平台的命令。并坚持使用它。 例如

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

两个。选择支持所有目标平台的库和工具包。像Qt和boost这样的工具包可以用来掩盖平台特定的粘性物。

boost和Qt都具有高功能的定时器,并且是可扩展的。我建议你查一下。

答案 3 :(得分:2)

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

  

描述:
  alarm()安排SIGALRM信号在seconds秒内传递给进程。

并在Windows上使用cygwin。

答案 4 :(得分:2)

你所做的事情是最简单的。

它耗费了太多的CPU,因为它很难进行检查(计时器是否过期了?) 或者其他什么。

要解决这个问题,请将睡眠(1)或操作系统相当于主要内容的短暂睡眠 循环,你会得到你需要的东西。

答案 5 :(得分:1)

使用sleep函数..和函数指针

使用睡眠功能不会消耗处理器时间...您可以使用函数指针在计时器到期时通知。如果你不需要事件,你可以简单地使用睡眠/延迟功能

编辑执行smallduck建议的操作。使用宏来当前调用Approlicateate操作系统调用(如果你想避免使用boost)...使用其他任何东西,那么timer不会准确。

答案 6 :(得分:1)

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

答案 7 :(得分:1)

您可以多次调用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);
  }

 ...
}

优于sleep()的优点是您在等待时仍可以执行代码。例如......轮询外部停止信号等

答案 8 :(得分:1)

这不是一项微不足道的任务,因为根据您的要求,它可能非常复杂。

定时器的问题在于,如果你想要一个好的计时器,你可能需要超越c ++(/ c)进入OS调用领域,导致你最终得到一个特定于操作系统的解决方案或者使用像boost这样的库来包装它

我主要在Windows中编程,所以我的建议来自那个领域:

在Windows中你当然可以使用一个定时器(NULL),但是大多数情况下,当你在等待时,你不想用循环来记录CPU。使用睡眠是一种方式,但我通常采取使用对象等待的方法。对象信号或超时都会发生。例如。为了等待10秒:

res = WaitForSingleObject( someobjecthandle, 10000 );

如果返回值超时我知道我等了10秒,否则对象以某种方式发出信号而我没有等待10秒。现在使用它可以创建一个有效的计时器。

另一种更有效的方法是创建一个单独的计时器线程(再次使用Windows),它定期向消息循环发送消息。

第三种方法是创建一个实际计时器的线程,你用一个参数启动线程,这次线程休眠(好吧我知道你不想使用它但你可以在线程内使用另一个MsgWaitForMultipleObjects函数如果你想过早地杀死计时器,那就做出反应)并在线程的句柄上做一个WaitForSingleObject,当它发出时间已经结束(或超时)时。

还有更多的方法,但我希望我至少给你一些想法:)

答案 9 :(得分:1)

很多这些答案都包含一些被称为“忙碌等待”的事情。在99%的情况下,在while()循环中反复检查时间是一个坏主意。

我想你可能想退一步,稍微改变一下问题。

听起来你想要一个程序在给定条件下关闭某些东西。

所以你有几个选择。您可以经常“唤醒”后台程序并检查是否满足条件(使用sleep / usleep,这是所有操作系统上所有语言的标准功能)。

或者您可以无限期地处理该过程,直到发生某种类型的事件。这可能最好通过信号或某种类型的等待函数在C中完成。

很难确切地说出你想要什么,因为很难说出你的待机/关闭条件如何得到满足以及它们是如何被触发的。

您可能希望电池监控程序执行某种类型的IPC,或者在需要待机时将某种类型的虚拟文件写入已知目录。使用IPC,您可以使用某种类型的wait()函数,该函数在将信号或IPC发送到后台进程时激活。使用文件方法,您可以sleep(),并在每次唤醒时检查该文件是否存在。

您也可以轻松使用网络/套接字来执行此操作。监听环回接口(127.0.0.1)和预定义端口。现在等到数据进入该套接字。当电池监视器需要待机时,他会通过环回向您的新进程发送一条简单的消息。这将有效地使用0 cpu。

也可能有其他方法,但我认为这应该给你一个大致的想法。

答案 10 :(得分:0)

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

答案 11 :(得分:0)

如果需要使用单个线程运行多个计时器,那么维护一个包含活动计时器的哈希表是一种非常好的方法。您使用到期时间来形成哈希键。每个计时器都会勾选您,然后在哈希表中搜索已过期的计时器。

答案 12 :(得分:0)

你总是可以玩线程。一个主线程可以是以特定间隔执行的任务/作业的调度。但后来我们进入了调度领域,这是操作系统所做的事情。正如GMan所说,你突然开始开发自己的操作系统,或者模仿部分操作系统功能。

答案 13 :(得分:-2)

  void SimpleTimer(int timeinterval)
  {
       int starttime, currenttime, difference;
       starttime = time(null);

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