寻找Linux下的实时计时事件

C/C++ - Looking for Realtime Timing Events under Linux

本文关键字:事件 实时 Linux 寻找      更新时间:2023-10-16

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

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

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

无限检查是否到了运行时间,缺点是(太)占用CPU资源。
一直睡到时间到了,缺点是时间不够精确。睡眠时间只是一个指导,它可以睡得更多。

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

无论你使用什么——select(), epoll(), usleep(), settimer()。有些方法可以"接受"更高分辨率的超时,有些则不能。但是Linux不是一个实时操作系统,甚至不应该期望它在那个时间精确地唤醒您的进程。现在,即使您旋转CPU,内核也可以很容易地挂起您的进程,如果它决定将该CPU分配给其他进程或中断处理程序。

从API的角度来看(以及最近的趋势),你可能应该坚持使用timerfd() -你可以告诉它使用什么时钟,它与Linux事件调度机制(epoll, AIO等)的其余部分很好地集成。

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

事实上,假设您在一台普通的x86_64服务器上运行一个新鲜的香草内核,它不是高负载的,期望您的唤醒时间在50µs左右(您可以很容易地对它进行基准测试,以获得您的系统的大致想法)。

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

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

另一种方法是依赖于某些硬件设备(如GPS卡)的定时。您的程序将对外部事件作出反应,而不是尝试为自己计时。例如,硬件设备可以公开一个"文件"。您的程序将打开它并阻塞在read()上。每100毫秒,硬件设备发送一些数据给你。

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

[…可以让你用严格的时间约束为你的喜好编写应用程序操作系统。像Linux本身一样,这个软件是一个社区的努力。

来自初学者指南:

RTAI提供了与Linux内核核心相同的服务,并添加了工业实体的特性time操作系统它基本上由中断分派器组成:RTAI主要捕获外围设备中断,必要时将它们重新路由到Linux。这不是一种侵扰修改内核;它使用HAL(硬件抽象层)的概念来获取从Linux获取信息并捕获一些基本函数。这个HAL提供了很少的依赖项到Linux内核。这导致在Linux内核中进行简单的调整,从不同版本的Linux以及更容易使用其他操作系统而不是RTAI。RTAI认为Linux是在没有实时活动发生时运行的后台任务。

您还可以考虑Linux特定的timerfd_create(2)和friends-(与poll(2)一起用于多路复用/等待,或一些事件库,如libevlibevent,或Gtk或Qt事件循环,它们将在内部调用poll)或Posix timer_create(2)。参见clock_gettime(2)和friends

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

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

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