我在Linux系统上运行了一个线程,我需要以尽可能准确的间隔执行。例如。每隔ms执行一次。
目前,这是通过使用
创建计时器来完成的 timerfd_create(CLOCK_MONOTONIC, 0)
,然后使用
在结构中传递所需的休眠时间 timerfd_settime (fd, 0, &itval, NULL);
对此计时器执行阻塞读取调用,该计时器停止线程执行并报告丢失的唤醒调用。
问题在于,在更高的频率下,即使CPU使用率低于10%,系统也会开始失去最后期限。我认为这是由于调度程序没有经常唤醒线程来检查阻塞调用。是否有一个命令可以用来告诉调度程序在可能的情况下以一定的间隔唤醒线程? 繁忙等待是一个糟糕的选择,因为系统处理许多其他任务。
谢谢。
答案 0 :(得分:5)
你需要获得RT linux *,然后定期提高你想要唤醒的进程的RT优先级。
除此之外,我没有在您的代码中看到问题,如果您的流程没有被阻止,它应该可以正常工作。
(*)RT linux - 应用了一些实时调度补丁的操作系统。
答案 1 :(得分:2)
减少调度程序延迟的一种方法是使用实时调度程序(如SCHED_FIFO)运行您的进程。见sched_setscheduler。
这通常会大大改善延迟,但仍然没有什么保证,为了进一步减少延迟峰值,你需要转向Linux的实时操作,或者像VxWorks,RTEMS或QNX这样的实时操作系统。
答案 2 :(得分:1)
除非你在实际的“实时操作系统”上运行它,否则你将无法做你想做的事。
答案 3 :(得分:1)
如果这只是Linux for x86系统,我会选择HPET计时器。我认为所有现代PC都内置了这个硬件计时器,而且非常非常准确。我允许你定义每毫秒调用一次的回调,在这个回调中你可以做你的计算(如果它们很简单)或只是使用一些同步对象触发其他线程工作(例如条件变量) 以下是如何使用此计时器http://blog.fpmurphy.com/2009/07/linux-hpet-support.html
的一些示例答案 4 :(得分:1)
除了将调度类设置为SCHED_FIFO
之外的其他建议,您还需要使用一个编译时间足够高的Linux内核,以满足您的截止日期。
例如,使用100 {250} CONFIG_HZ
编译的内核(每秒定时器中断)永远不会更快地响应定时器事件。
您还必须将计时器设置为比您实际需要的一点点更快,因为允许计时器超出其请求的时间但从不提前到期,这将为您提供更好的结果。如果您需要1毫秒,那么我建议请求999我们。