5

我正在寻找一种在 Linux 下在 C/C++ 中进行计时事件的方法。
例如,每 100 毫秒执行一段代码。(不多不少,软实时)

到目前为止,我看到的唯一选择是:

  • 无限循环,每次检查是否到了执行时间。
  • 休眠线程直到运行时间。

无限检查是否到了运行时间,缺点是它(太)CPU 密集型。
一直睡到时间,缺点是不准确。睡眠时间只是一个指导方针,它可以睡得更多。

现在我想知道你们中是否有人知道如何在 Linux 下用 C/C++ 进行实时计时事件。

4

5 回答 5

4

你要使用什么几乎无关紧要——a select(), epoll(), usleep(), settimer(). 有些方法可以“采取”更高分辨率的超时,有些则不能。但是 Linux 不是一个实时操作系统,甚至不应该期望它会在那个时候唤醒你的进程。现在,即使您旋转 CPU,如果内核决定将该 CPU 分配给其他进程或中断处理程序,内核也可以轻松挂起您的进程。

从 API 的角度来看(以及最近的趋势),您可能应该坚持使用timerfd()——您可以告诉它使用什么时钟,并且它与 Linux 的其他事件调度机制(epoll、AIO 等)很好地集成在一起。

除此之外,它超出了您作为程序员的控制范围。为了从 Linux 获得近乎实时的行为,通常需要付出很大的努力。它的范围从构建一个定制的修补内核和为整个世界配置亲和力,包括中断屏蔽,到修补你的 BIOS 和调整硬件。

实际上,假设您在负载不高的商品 x86_64 服务器上运行新的 vanilla 内核,预计您的唤醒时间大约为 50 µs(您可以轻松地对其进行基准测试以大致了解您的系统)。

于 2013-02-28T19:20:13.627 回答
3

在非实时操作系统上运行,没有任何用户空间方法是完全可靠的。没错,睡眠是不精确的,你可能会睡过头,但循环也是如此:操作系统可能无法及时安排你的任务,你会错过你的时间。

根据您需要的可靠性,考虑使用实时操作系统 (RTOS),例如QNXRTLinux。RTLinux 的 wiki 有点过时了,所以我不确定它的活跃程度。

另一种方法是依靠某些硬件设备(例如 GPS 卡)的计时。您的程序将对外部事件做出反应,而不是尝试自行计时。例如,硬件设备可以公开一个“文件”。您的程序将打开它并阻止read(). 每隔 100 毫秒,硬件设备就会向您发送一些数据。

于 2013-02-28T19:10:39.883 回答
1

你可以试试RTAI,Linux 的实时应用程序接口。

[...] 让您可以为自己喜欢的操作系统编写具有严格时序约束的应用程序。与 Linux 本身一样,该软件是社区的成果。

从初学者指南:

RTAI 提供与 Linux 内核核心相同的服务,增加了工业实时操作系统的特性。它基本上由一个中断调度程序组成:RTAI 主要捕获外围设备中断,并在必要时将它们重新路由到 Linux。它不是对内核的侵入性修改;它使用 HAL(硬件抽象层)的概念从 Linux 获取信息并捕获一些基本功能。此 HAL 对 Linux 内核的依赖很少。这导致在 Linux 内核中的简单适配、从版本到 Linux 版本的简单 RTAI 移植以及更容易使用其他操作系统而不是 RTAI。RTAI 将 Linux 视为在没有实时活动发生时运行的后台任务。

于 2013-02-28T19:07:18.453 回答
0

您还可以考虑 Linux 特定的timerfd_create(2) -and friends-(使用poll(2)进行多路复用/等待,或者一些事件库,如libevor libevent,或者 Gtk 或 Qt 事件循环,它们将poll在内部调用)或 Posix timer_create( 2)。另请参阅clock_gettime(2)和朋友

我强烈建议阅读time(7)手册页。它解释了很多。正如 Vlad回答的那样,Linux 不是真正的实时内核(即使它可能很接近)。

于 2013-02-28T19:59:49.917 回答
-1

查看 libevent: http: //libevent.org/

当文件描述符上发生特定事件或达到超时后,libevent API 提供了一种执行回调函数的机制。此外,libevent 还支持由于信号或定期超时而引起的回调。

于 2013-02-28T19:04:09.207 回答