Linux 定时器间隔

Linux timer interval

我想要运行一个间隔为 5 毫秒的计时器。我创建了一个 Linux 计时器,当 sigalrm_handler 被调用时,我正在检查上一次调用的经过时间。我得到的时间如下: 4163、4422、4266、4443、4470 4503、4288 微秒,当我希望间隔大约为 5000 微秒且错误最少时。我不知道为什么这个间隔不是恒定的,但它会变化并且比应该的要低得多。

这是我的代码:

static int time_count;  
static int counter;  
struct itimerval timer={0};  


void sigalrm_handler(int signum)  
{  
  Serial.print("SIGALRM received, time: ");  
  Serial.println(micros()-time_count);  
  time_count=micros();  
}  


void setup() {  
  Serial.begin(9600);   
  timer.it_value.tv_sec = 1;  

  timer.it_interval.tv_usec = 5000;  

  signal(SIGALRM, &sigalrm_handler);  
  setitimer(ITIMER_REAL, &timer, NULL);  
  time_count = micros();  
}  

I want to run a timer with interval of 5 ms.

您可能无法可靠地获得那个时间段,因为它比合理的 PC 硬件可以处理的要小。

根据经验法则,50 Hz(或可能是 100Hz)可能是您可以获得的最高可靠频率。而且这不是软件的问题,而是硬件的问题

想想您的典型处理器缓存(几兆字节)。您可能需要几毫秒来填充它。或者考虑处理页面错误的时间;可能需要一毫秒以上。

而且英特尔爱迪生不是 top-fast 处理器。如果将数字转换为字符串并在某个屏幕上显示该字符串可能需要大约一毫秒(但我让您检查一下),我不会感到惊讶。这可以解释你的数字。

关于软件,另见time(7) (or consider perhaps some busy waiting方法内核;我不推荐这样做)。

通过 运行 几次 cat /proc/interrupts 命令在 shell 中查看 /proc/interrupts 几次(参见 proc(5))。您可能会发现内核被中断的频率低于每隔一毫秒或几毫秒一次。

顺便说一句,您的信号处理程序调用 non-async-signal-safe 函数(undefined behavior). Read signal(7) & signal-safety(7)

所以看起来你的整个方法都是错误的。

也许您想要一些 RTOS, at least if you need some hard real-time(然后,您可能会考虑将硬件升级到更快、成本更高的硬件)。