Попробуйте изменить его следующим образом, это должно в значительной степени гарантировать, что он никогда не пропустит пробуждение, но будьте осторожны с ним, поскольку выполнение приоритета в реальном времени может сильно блокировать вашу машину, если она не спит, также вам может потребоваться установить все так, чтобы у вашего пользователя была возможность запускать вещи с приоритетом в реальном времени (см. /etc/security/limits.conf
)
#include <sys/timerfd.h>
#include <time.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <sched.h>
int main(int argc, char *argv[])
{
int timerfd = timerfd_create(CLOCK_MONOTONIC,0);
int milliseconds = atoi(argv[1]);
struct itimerspec timspec;
struct sched_param schedparm;
memset(&schedparm, 0, sizeof(schedparm));
schedparm.sched_priority = 1; // lowest rt priority
sched_setscheduler(0, SCHED_FIFO, &schedparm);
bzero(&timspec, sizeof(timspec));
timspec.it_interval.tv_sec = 0;
timspec.it_interval.tv_nsec = milliseconds * 1000000;
timspec.it_value.tv_sec = 0;
timspec.it_value.tv_nsec = 1;
int res = timerfd_settime(timerfd, 0, &timspec, 0);
if(res < 0){
perror("timerfd_settime:");
}
uint64_t expirations = 0;
int iterations = 0;
while( res = read(timerfd, &expirations, sizeof(expirations))){
if(res < 0){ perror("read:"); continue; }
if(expirations > 1){
printf("%ld expirations, %d iterations\n", expirations, iterations);
break;
}
iterations++;
}
}
Если вы используете потоки, вы должны использовать pthread_setschedparam
вместо sched_setscheduler
.
Realtime также не о низкой задержке, а о гарантиях, RT означает, что если вы хотите просыпаться ровно раз в секунду на секунду, вы БУДЕТЕ, нормальное планирование не дает вам этого, возможно, вы решите разбудить Вы поднялись на 100 мс позже, потому что в любом случае у него была другая работа. Если вы хотите просыпаться каждые 10 мс, и вам ДЕЙСТВИТЕЛЬНО это нужно, тогда вы должны настроить себя на выполнение задачи в реальном времени, тогда ядро будет разбудить вас каждые 10 мсек в обязательном порядке. Если задача реального времени с более высоким приоритетом не занята работой.
Если вам нужно гарантировать, что ваш интервал пробуждения ровно какое-то время, то не имеет значения, 1 мс или 1 секунду, вы не получите его, если не выполните задачу в реальном времени. Существуют веские причины, по которым ядро сделает это за вас (экономия энергии - одна из них, более высокая пропускная способность - другая, есть и другие), но это вполне оправдано, так как вы никогда не говорили, что вам нужны лучшие гарантии. Большинство вещей на самом деле не должны быть такими точными или никогда не пропустить, так что вам стоит задуматься о том, действительно ли вам это нужно.
цитата из http://www.ganssle.com/articles/realtime.htm
Трудная задача или система реального времени
тот, где деятельность просто должна быть
завершено - всегда - указанным
крайний срок. Крайний срок может быть
конкретное время или интервал времени, или
может быть прибытие какого-то события. Жесткий
задачи реального времени проваливаются по определению,
если они пропустят такой срок.
Обратите внимание, что это определение не дает
предположения о частоте или
период выполнения заданий. Микросекунда или
неделю - если пропущен срок
вызывает сбой, то задача имеет
жесткие требования в реальном времени.
Мягкое реальное время в значительной степени то же самое, за исключением того, что пропущенный крайний срок, хотя и нежелательный, не является концом света (например, воспроизведение видео и аудио - это мягкие задачи в реальном времени, вы не хотите пропустить отображение кадра, или не хватает буфера, но если вы это сделаете, это всего лишь мгновенный икота, и вы просто продолжите). Если то, что вы пытаетесь сделать, это «мягкое» реальное время, я бы не стал работать с приоритетом в реальном времени, так как вы обычно должны вовремя получать пробуждения (или, по крайней мере, близко к нему).
EDIT:
Если вы не работаете в режиме реального времени, ядро по умолчанию выдаст любые таймеры, которые вы сделаете несколько «провисшими», чтобы он мог объединить ваш запрос, чтобы проснуться с другими событиями, которые происходят в моменты, близкие к тому, который вы запрашивали (что если другое событие находится в пределах вашего «расслабленного» времени, оно не разбудит вас в тот момент, когда вы попросили, но немного раньше или позже, в то же время оно уже собиралось сделать что-то еще, это экономит энергию).
Для получения дополнительной информации см. Тайм-ауты с высоким (но не слишком высоким) разрешением и Слабая работа таймера (заметьте, я не уверен, что любая из этих вещей является именно тем, что на самом деле в ядре, поскольку обе эти статьи посвящены обсуждению списков рассылки lkml, но что-то вроде первого действительно в ядре.