简体   繁体   English

C/C++ - 寻找Linux下的实时计时事件

[英]C/C++ - Looking for Realtime Timing Events under Linux

I'm looking for a way to do timing events in C/C++ under Linux.我正在寻找一种在 Linux 下用 C/C++ 进行计时事件的方法。
Eg execute a piece of code every 100 milliseconds.例如,每 100 毫秒执行一段代码。 (No more, no less, soft real-time) (不多不少,软实时)

The only options I've seen till now are:到目前为止,我看到的唯一选择是:

  • Looping infinitely, and check every time if it is time to execute.无限循环,每次都检查是否到了执行的时候。
  • Sleeping the thread until it is time to run.休眠线程,直到需要运行。

Infinitely checking if it is time to run, has the disadvantage that it is (too) CPU intensive.无限地检查是否到了运行的时间,缺点是它(太)占用 CPU。
Sleeping until it is time, has the disadvantage that it is not precise.睡到它的时间,缺点是它不精确。 The sleep-time is just a guideline, it could sleep way more.睡眠时间只是一个指导方针,它可以睡得更多。

Now I was wondering if any of you know how to do real-time timing events in C/C++ under Linux.现在我想知道你们有没有人知道如何在 Linux 下用 C/C++ 做实时计时事件。

It almost doesn't matter what you are going to use — a select() , epoll() , usleep() , settimer() .您将使用什么几乎无关紧要 - select()epoll()usleep()settimer() Some methods can "take" a higher-resolution timeout, some can't.有些方法可以“采取”更高分辨率的超时,有些则不能。 But Linux is not a real-time OS and should not even expect it to wake up your process at precisely that time.但是 Linux 不是实时操作系统,甚至不应该期望它恰好在那个时间唤醒您的进程。 Now, even if you spin the CPU, the kernel can easily suspend your process shall it decide to allocate that CPU to some other process or an interrupt handler.现在,即使您旋转 CPU,内核也可以轻松挂起您的进程,如果它决定将该 CPU 分配给某个其他进程或中断处理程序。

From the API perspective (as well as recent trends), you should probably stick with timerfd() — you can tell it what clock to use, and it integrates nicely with the rest of Linux event dispatching mechanisms (epoll, AIO, etc).从 API 的角度(以及最近的趋势)来看,您可能应该坚持使用timerfd() — 您可以告诉它使用什么时钟,并且它与 Linux 的其他事件调度机制(epoll、AIO 等)很好地集成在一起。

Other than that, its outside your control as a programmer.除此之外,它超出了您作为程序员的控制范围。 A great effort is usually needed in order to get near-real-time behavior from Linux.通常需要付出很大的努力才能从 Linux 获得近乎实时的行为。 It ranges from building a custom patched kernel and configuring affinity for the entire world including shielding of interrupts, to patching your BIOS and tuning the hardware.它的范围从构建自定义补丁内核和配置整个世界的亲和性(包括屏蔽中断)到修补 BIOS 和调整硬件。

As it is, assuming you run a fresh vanilla kernel on a commodity x86_64 server which is not highly loaded, expect your wake-up time to be somewhere around 50 µs (you can easily benchmark it to get a rough idea for your system).事实上,假设您在负载不高的商用 x86_64 服务器上运行一个新的 vanilla 内核,预计您的唤醒时间约为 50 微秒(您可以轻松地对其进行基准测试以大致了解您的系统)。

Running on a non-realtime OS, no userspace approach is entirely reliable.在非实时操作系统上运行,没有任何用户空间方法是完全可靠的。 You're right that sleeping is imprecise and you may oversleep, but the same applies to looping: the OS may not schedule your task in time, and you'll miss your slot.你是对的,睡眠是不精确的,你可能会睡过头,但同样适用于循环:操作系统可能不会及时安排你的任务,你会错过你的时间。

Depending on how reliable you need this to be, consider a real-time operating system (RTOS) like QNX or RTLinux .根据您需要的可靠性,考虑使用实时操作系统 (RTOS),如QNXRTLinux RTLinux's wiki is a bit out of date, so I am not sure how active it is. RTLinux 的 wiki 有点过时,所以我不确定它有多活跃。

Another approach is to rely on the timing of some hardware device (such as a GPS card).另一种方法是依靠某些硬件设备(例如 GPS 卡)的计时。 Your program would react to the external event rather than try to time itself.您的程序会对外部事件做出反应,而不是尝试自己计时。 For example, the hardware device could expose a "file".例如,硬件设备可以公开一个“文件”。 Your program would open it and block on read() .您的程序将打开它并阻塞read() Every 100 ms, the hardware device sends some data to you.每 100 毫秒,硬件设备会向您发送一些数据。

You could try RTAI , the Real Time Application Interface for Linux.您可以尝试RTAI ,Linux 的实时应用程序接口。

[...] which lets you write applications with strict timing constraints for your favourite operating system. [...] 允许您为自己喜欢的操作系统编写具有严格时间限制的应用程序。 Like Linux itself this software is a community effort.就像 Linux 本身一样,这个软件是社区的努力。

From the beginners guide:从初学者指南:

RTAI offers the same services of the Linux kernel core, adding the features of an industrial real time operating system . RTAI 提供与 Linux 内核相同的服务,增加了工业实时操作系统的功能 It consists basically of an interrupt dispatcher: RTAI mainly traps the peripherals interrupts and if necessary re-routes them to Linux.它基本上由一个中断调度程序组成:RTAI 主要捕获外围设备中断,并在必要时将它们重新路由到 Linux。 It is not an intrusive modification of the kernel;它不是对内核的侵入性修改; it uses the concept of HAL (hardware abstraction layer) to get information from Linux and to trap some fundamental functions.它使用 HAL(硬件抽象层)的概念从 Linux 获取信息并捕获一些基本功能。 This HAL provides few dependencies to Linux Kernel.此 HAL 对 Linux 内核的依赖很少。 This leads to a simple adaptation in the Linux kernel, an easy RTAI port from version to version of Linux and an easier use of other operating systems instead of RTAI.这导致在 Linux 内核中进行简单的调整,在 Linux 的不同版本之间进行简单的 RTAI 移植,以及更容易使用其他操作系统而不是 RTAI。 RTAI considers Linux as a background task running when no real time activity occurs. RTAI 将 Linux 视为在没有实时活动发生时运行的后台任务。

You might also consider the Linux specific timerfd_create(2) -and friends- (with poll(2) for multiplexing/waiting, or some event library like libev or libevent , or Gtk or Qt event loops, which will call poll internally) or the Posix timer_create(2) .您还可以考虑 Linux 特定的timerfd_create(2) -和朋友-(使用poll(2)进行多路复用/等待,或一些事件库,如libevlibevent ,或 Gtk 或 Qt 事件循环,它们将在内部调用poll )或Posix timer_create(2) See also clock_gettime(2) and friends另见clock_gettime(2)和朋友

I strongly suggest reading time(7) man page.我强烈建议阅读time(7)手册页。 It explains a lot.它解释了很多。 And as Vlad answered , Linux is not a true real time kernel (even if it may be close).正如 Vlad回答的那样,Linux 不是真正的实时内核(即使它可能很接近)。

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

The libevent API provides a mechanism to execute a callback function when a specific event occurs on a file descriptor or after a timeout has been reached. libevent API 提供了一种机制,可以在文件描述符上发生特定事件或达到超时后执行回调函数。 Furthermore, libevent also support callbacks due to signals or regular timeouts.此外,libevent 还支持由于信号或常规超时而引起的回调。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM