Функции сна гарантируют, что вы спите как минимум определенное время. Поскольку Linux не является операционной системой реального времени, вы НЕ МОЖЕТЕ быть уверены, что она будет находиться в спящем режиме ТОЛЬКО необходимое количество времени. Это проблема, так как вы НЕ МОЖЕТЕ рассчитывать на это значение. Как вы указали, случается, что время сна действительно БОЛЬШОЕ.
Планировщик Linux не может этого гарантировать. С ОС реального времени вы можете получить это.
Ваша формула в некотором смысле неверна, но я думаю, что это не может быть причиной того, что у вас такой большой сон. С помощью этого фрагмента я проверяю две формулы и получаю одинаковый результат:
#include <unistd.h>
#include <sys/time.h>
#include <time.h>
#include <stdio.h>
int main()
{
struct timeval start, end;
long mtime, mtime2, start_time, end_time, seconds, useconds;
while(1)
{
gettimeofday(&start, NULL);
usleep(2000);
gettimeofday(&end, NULL);
seconds = end.tv_sec - start.tv_sec;
useconds = end.tv_usec - start.tv_usec;
mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5;
start_time = ((start.tv_sec) * 1000 + start.tv_usec/1000.0) + 0.5;
end_time = ((end.tv_sec) * 1000 + end.tv_usec/1000.0) + 0.5;
mtime2 = end_time - start_time;
if(mtime > 10 || mtime2 > 10)
{
printf("WTF: %ld\n", mtime);
printf("WTF2: %ld\n", mtime2);
}
}
return 0;
}
Результаты:
$ gcc test.c -o out -lrt && ./out
WTF: 11
WTF2: 12
WTF: 21
WTF2: 21
Я подумал, что это неправильно, поскольку часть useconds является циклической и может привести к большой отрицательной разнице. Но это не приведет к такому большому времени, когда вы используете длинные целые числа со знаком ...
my2cents
Редактировать : от человека до сна:
Текущая реализация
nanosleep () основан на нормальном
механизм таймера ядра, который имеет
разрешение 1 / Гц с (см. время (7)).
Поэтому nanosleep () всегда делает паузу
по крайней мере, на указанное время,
однако это может занять до 10 мс дольше
чем указано до процесса
снова становится работоспособным Для того же
причина, значение возвращается в случае
доставленный сигнал в * rem обычно
округляется до следующего большего кратного
1 / Гц с.