代码之家  ›  专栏  ›  技术社区  ›  Secko

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

c c++
  •  5
  • Secko  · 技术社区  · 15 年前

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

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

    编辑:

    该程序在一组Linux和Windows服务器上工作,因此它是一个多平台环境。我不想使用unsleep或sleep函数,因为我正在尝试从头开始编写所有内容。

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

    14 回复  |  直到 15 年前
        1
  •  9
  •   sharptooth    15 年前

    最好的选择是使用操作系统原语,该原语将程序挂起一段给定的时间(如Windows中的Sleep())。程序运行的环境很可能有某种机制来执行此操作或类似操作。这是避免轮询和消耗CPU时间的唯一方法。

        2
  •  5
  •   small_duck    15 年前

    • 睡眠(在Windows中)
    • usleep(在Unix中)
    • boost::此线程::睡眠(无处不在)

        3
  •  3
  •   Fox    15 年前

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

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

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

        4
  •  2
  •   Adrian Panasiuk    15 年前

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


    alarm()安排将SIGALRM信号发送到中的进程 seconds 秒。

    并在windows上使用cygwin。

        5
  •  2
  •   hookenz    15 年前

    你已经在做的事情是最简单的。

    它消耗了太多的CPU,因为它很难完成您的检查(计时器是否过期?) 或者别的什么。

    要解决这个问题,请将usleep(1)或其他操作系统中相当于很短睡眠时间的操作系统放在主系统中 循环,你就会得到你需要的。

        6
  •  1
  •   Mehrdad Afshari    15 年前

        7
  •  1
  •   Umair Ahmed    15 年前

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

    编辑

        8
  •  1
  •   kjfletch    15 年前

    #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()相比,它的优点是在等待时仍然可以执行代码。例如轮询外部停止信号等。

        9
  •  1
  •   mox1    15 年前

    很多答案都包括所谓的“忙碌等待”。在while()循环中反复检查时间在99%的情况下都是个坏主意。

    我想你可能想退一步,换一种方式处理这个问题。

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

    所以你有几个选择。您可以每隔一段时间“唤醒”您的后台程序并检查是否满足条件(使用sleep/usleep,这是所有操作系统上所有语言的标准函数)。

    或者,您可以无限期地对流程进行后台处理,直到发生某种类型的事件。这可能最好在C语言中通过信号或某种类型的等待函数来实现。

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

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

        10
  •  1
  •   halfer Rajnish Kumar    4 年前

    这不是一项琐碎的任务,因为根据您的需求,它可能相当复杂。

    计时器的问题是,如果你想要一个好的计时器,你可能需要超越C++/C,进入操作系统调用的领域,从而最终得到一个特定于操作系统的解决方案,或者使用一些库(如boost)来包装它。

    我主要在Windows中编程,因此我的建议来自该领域:

    在Windows中,您当然可以使用 timer(NULL)

    res = WaitForSingleObject( someobjecthandle, 10000 );
    

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

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

        11
  •  0
  •   Vatine    15 年前

    如果您所需要的只是一段代码片段,可以让您的程序休息,那么调用sleep就足够了(如果您可以使用第二粒度)。

        12
  •  0
  •   Howard May    15 年前

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

        13
  •  0
  •   ralphtheninja    15 年前

        14
  •  -2
  •   user134570    15 年前
      void SimpleTimer(int timeinterval)
      {
           int starttime, currenttime, difference;
           starttime = time(null);
    
           do
           {
                currenttime = time(null); 
                difference = currenttime - starttime;
           }
           while (difference < timeinterval);
      }