【问题标题】:Loops/timers in CC中的循环/计时器
【发布时间】:2011-07-29 06:07:37
【问题描述】:

如何在 C 中创建计时器?

我想要一段代码不断地从 gps 解析器输出中获取数据。

有没有很好的库,还是应该自己写?

【问题讨论】:

  • 你能再具体一点吗?你是如何解析输出的?真的很难理解你在问什么。
  • 不用担心解析。我只想知道如何在 C 中创建一个计时器函数,该函数循环并执行其语句。
  • 基于后来的cmets,在标签中加入了Linux

标签: c linux loops timer


【解决方案1】:

最简单的方法:

#include <pthread.h>

void *do_smth_periodically(void *data)
{
  int interval = *(int *)data;
  for (;;) {
    do_smth();
    usleep(interval);
  }
}

int main()
{
  pthread_t thread;
  int interval = 5000;

  pthread_create(&thread, NULL, do_smth_periodically, &interval)

  ...
}

【讨论】:

  • 不反对,但他也提到他希望它在单独的线程中运行,因此创建线程并在其中运行 do_smth_periodically() 的代码也会有所帮助。此外,此方法将导致循环的整个“墙”时间根据每次迭代执行do_smth() 所需的时间而变化。不过,这很可能对他的申请没问题。
  • 竞争条件警告:当从另一个函数而不是main()调用pthread_create时,注意将interval变量保留在内存中,因为interval可能在线程分配之前超出范围*data 第一行的参数。
【解决方案2】:

在 POSIX 系统上,您可以创建(并捕获)alarm。警报很简单,但只需几秒钟即可设置。如果您需要比秒更精细的分辨率,请使用setitimer

struct itimerval tv;
tv.it_interval.tv_sec = 0;
tv.it_interval.tv_usec = 100000;  // when timer expires, reset to 100ms
tv.it_value.tv_sec = 0;
tv.it_value.tv_usec = 100000;   // 100 ms == 100000 us
setitimer(ITIMER_REAL, &tv, NULL);

并通过设置sigaction 定期捕捉计时器。

【讨论】:

    【解决方案3】:

    一个人不会“在 C 中创建一个计时器”。 C 标准中没有关于时间或调度的任何内容,因此如何完成则由操作系统决定。

    这对于 C 菜鸟来说可能是一个合理的问题,因为许多语言确实支持这样的事情。 Ada 会这样做,而且我相信 C++ 的下一个版本可能会这样做(Boost 现在支持它)。我很确定 Java 也可以做到。

    在 linux 上,可能最好的方法是使用pthreads。特别是,您需要调用 pthread_create() 并将您的例程的地址传递给它,该地址可能包含一个在底部调用 sleep()(或 usleep())的循环。

    请注意,如果你想做一些近似实时调度的事情,仅仅做一个愚蠢的usleep() 是不够的,因为它不会考虑循环本身的执行时间。对于这些应用程序,您需要设置 periodic timer 并等待。

    【讨论】:

    • 那么我如何在自己的线程中循环执行一个函数呢?
    • @Helium3 - 要么使用操作系统调用(这取决于你正在运行的操作系统,你还没有告诉我们),要么使用更好的语言。
    • 它将在 Pandaboard 上的 Ubuntu 上运行。
    • [pedantic] 一种“更好”的语言是通过时间支持来定义的?好笑。
    • @stijn - 对于这个特定的目的,是的,一种真正支持线程的语言(即使在像 boost 这样的可移植库中)会更好。 C 也有其优势,但这不是其中之一。
    【解决方案4】:

    SDL 在 C 语言中提供了一个跨平台计时器。

    http://www.libsdl.org/cgi/docwiki.cgi/SDL_AddTimer

    【讨论】:

    • 它似乎是一个围绕多媒体设计的框架。他必须使用它的“主循环”并设置一个计时器回调。如果这种结构是可以接受的,可能会有用。
    • @T.E.D.它是为多媒体设计的,但我发现它的计时器和事件队列本身就很方便。
    【解决方案5】:

    如果您使用 Windows,则可以使用 SetTimer,否则您可以使用 timeGetTime_beginthreadex 构建一个计时器以及带有回调的计时器队列

    【讨论】:

      【解决方案6】:

      关于计时器的问题非常不具体,但我想到了两个功能可以帮助您:

      • sleep() 此函数将导致执行停止指定的秒数。如果您想更准确地指定睡眠时间,也可以使用 usleep 和 nanosleep
      • gettimeofday() 使用此函数,您可以在时间步之间停止。

      更多解释请参见手册页:)

      【讨论】:

        【解决方案7】:

        如果 gps 数据来自某个硬件设备,例如通过串行端口,那么您可能会考虑更改架构,以便在有更多数据时解析器启动您尝试运行的代码可用。

        它可以通过回调函数或发送事件来执行此操作 - 实际实现将取决于您可用的内容。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-05-19
          • 2014-03-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-12-02
          相关资源
          最近更新 更多