Попробуйте изменить его следующим образом, это должно быть довольно много, чтобы он никогда не пропустил пробуждение, но будьте осторожны с ним, поскольку выполнение приоритета в реальном времени может заблокировать вашу машину, если она не спит, также вам может потребоваться настроить все так, что ваш пользователь имеет возможность запускать материал в реальном времени приоритет (см /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
.
Реальное время также не связано с низкой задержкой, то есть о гарантиях, RT означает, что если вы хотите проснуться ровно раз в секунду на втором, вы БУДЕТЕ, нормальное планирование не дает вам этого, оно может решить разбудите вас на 100 мс позже, потому что в любом случае в то время у него была другая работа. Если вы хотите просыпаться каждые 10 мс, и вам действительно нужно, тогда вы должны настроить себя как задачу в реальном времени, тогда ядро разбудит вас каждые 10 мс без сбоев.Если задача с более высоким приоритетом в реальном времени занята занятием.
Если вам нужно гарантировать, что ваш интервал пробуждения - это точно какое-то время, это не имеет значения, если это 1 мс или 1 секунда, вы не получите его, если не выполняете задачу в реальном времени. Есть веские причины, по которым ядро будет делать это с вами (экономия энергии - одна из них, более высокая пропускная способность - другая, есть и другие), но это хорошо в ее правах, так как вы никогда не говорили, что вам нужны лучшие гарантии. Большинство вещей на самом деле не обязательно должны быть такими точными или вам не нужно пропустить, поэтому вам следует подумать о том, действительно ли вам это нужно.
цитирую http://www.ganssle.com/articles/realtime.htm
Жесткое реальное время задачи или системы является одна, где деятельность просто должна быть завершена - всегда - по указанному сроку. Крайним сроком может быть определенное время или временной интервал , или может быть приходом какого-либо события. Жесткие задачи в реальном времени не работают, по определению, , если они пропустят такой срок.
Обратите внимание, что это определение не делает предположений о частоте или периодом задач. Микросекунда или в неделю - при отсутствии предельного срока вызывает отказ, тогда задача имеет жесткие требования к реальному времени.
Soft в реальном времени в значительной степени то же самое, за исключением того, что отсутствует срок, в то время как нежелательно, это не конец света (например, видео и аудио воспроизведения являются мягкими задач в реальном времени, вы не хотите пропустить отображение кадр или закончиться из буфера, но если вы делаете это всего лишь мгновенный икота, и вы просто продолжаете). Если то, что вы пытаетесь сделать, это «мягкое» в реальном времени, я бы не стал работать с приоритетом в реальном времени, так как вы обычно должны получать свои пробуждения вовремя (или, по крайней мере, близко к нему).
EDIT:
Если вы не работаете в реальном времени ядро по умолчанию дают таймеры вы сделать некоторые «слабину», так что он может объединить вашу просьбу, чтобы проснуться с другими событиями, которые происходят время от времени, близких к тот, который вы попросили (то есть, если другое событие находится в пределах вашего «слабого» времени, оно не разбудит вас в то время, когда вы спросили, но немного раньше или позже, в то же время он уже собирался сделать что-то еще, это экономит энергию).
Для немного дополнительной информации см High- (but not too high-) resolution timeouts и Timer slack (заметьте, я не уверен, если любой из этих вещей является именно то, что на самом деле в ядре, так как обе эти статьи о lkml обсуждения списка рассылки, но что-то как первый действительно находится в ядре
Мои данные о районе довольно ржавые. Кажется, вы хотите что-то делать в режиме реального времени. Проверьте Linux в режиме реального времени. В противном случае планировщик использует более длительную детализацию, чтобы избежать более высоких издержек. Вы хотели бы запустить свой процесс как RT (в реальном времени) один ('man sched_setparam') и, возможно, под root. Для нормальных процессов (например, игр или мультимедиа) вы выполняете (1) ожидание в узком цикле или (2) в каждом событии таймера вычисляете ошибку (ожидаемое фактическое время пробуждения) и берете ее в учетную запись при продвижении внутреннего времени, зависимого состояния. – Dummy00001
Спасибо за подсказку, но я не считаю 20 миллисекундными интервалами частью домена реального времени. Я имею в виду, что стандартная система, которой просят дождаться 10 миллисекунд, никогда не должна ждать 21 миллисекунды, RT звучит слишком много для этого. –
вы можете попробовать настроить свою программу на выполнение с приоритетом в реальном времени, вам, вероятно, не нужно использовать ядро RT Linux, в наши дни основная линия довольно хороша в реальном времени и с учетом того, что она никогда не пропустила более одного срока действия только с приоритетом RT должно быть достаточно, чтобы вы никогда не пропустили один – Spudd86