задержка времени в C. usleep

Я разрабатываю игровой сервер, написанный на C. И мне нужно разработать цикл с определенной частотой (50 раз в секунду) для выполнения алгоритма. Проблема в том, что я не могу поставить программу на паузу на точный временной интервал - 20000 микросекунд. Функция usleep(20000) работает около 30000 микросекунд. Результат всегда на 10000 микросекунд больше, чем ожидалось.

Вот мой простой пример кода:

#include <stdio.h>
#include <time.h>
#include <unistd.h>

int main( int argc, char ** argv )
{

        const unsigned long long nano = 1000000000;
        unsigned long long t1, t2;

        struct timespec tm;

        for(;;)
        {

                clock_gettime( CLOCK_REALTIME, &tm );
                t1 = tm.tv_nsec + tm.tv_sec * nano;

                usleep( 20000 );

                clock_gettime( CLOCK_REALTIME, &tm );
                t2 = tm.tv_nsec + tm.tv_sec * nano;

                printf( "delay: %ld\n", ( t2 - t1 ) / 1000 );
        }

        return 0;

}

И результат его работы:

$ ./a.out
delay: 29233
delay: 29575
delay: 29621
delay: 29694
delay: 29688
delay: 29732
delay: 29709
delay: 29706
delay: 29666
delay: 29702
delay: 29702
delay: 29705
delay: 29789
delay: 29619
delay: 29785
delay: 29634
delay: 29692
delay: 29708
delay: 29701
delay: 29703

Я также пробовал использовать функцию select(), но результат такой же, как и с sleep().

Объясните мне, пожалуйста, что не так с моим кодом.

p.s.:

$ uname -a
FreeBSD home.com 9.0-RELEASE FreeBSD 9.0-RELEASE #0: Tue Jan  3 07:46:30 UTC 2012     [email protected]:/usr/obj/usr/src/sys/GENERIC  amd64

person Andrew    schedule 08.10.2012    source источник
comment
По теме: Сон в течение определенного времени   -  person Christian Ammer    schedule 08.10.2012


Ответы (3)


Вместо того, чтобы спать на 20000 мксек, спите на время, оставшееся до следующего запуска, на основе вызова clock_gettime

I.e:

usleep( lasttime+20000-now ); // But make sure you don't sleep when the result is negative

Дело не в том, что у вашего кода есть проблема, но фактический вызов режима сна, считывание времени и т. Д. Требует времени, и система в любом случае не может спать на точное время, если оно не кратно ее точному тактовому циклу.

person Ofir    schedule 08.10.2012

Функции сна в системах, не работающих в реальном времени, не гарантируют, что они будут спать точно в указанный период; в загруженной системе процесс будет активирован только тогда, когда начнется его временной интервал. Или, , как указано на странице руководства, "активность системы может продлить сон на неопределенное время ».

Сумма, близкая к 10 мс, звучит так, будто частота kern.hz снижена до 100, , как некоторые рекомендуют для настройки ВМ.

Классический обходной путь для этой проблемы предлагает Ofir: вместо указания фиксированного интервала сна укажите оставшееся время сна. В среднем ваш цикл будет выполняться каждые 20 мсек, чего вы, скорее всего, хотите достичь.

person user4815162342    schedule 08.10.2012
comment
Чтобы добавить к ответу: команды сна освобождают процессор на установленное время. Во время этой задержки процесс не запрашивает процессор и не является частью выбора процесса планировщика. По истечении таймера процесс снова вступит в конкуренцию с другим процессом за использование ЦП. Дополнительная задержка возникает из-за того, что планировщик выбирает, выбирать или нет вашу программу в каждый раз во время выборов. - person M'vy; 10.10.2012

В usleep функции 1000000 = 1 сек.

Попробуйте соответствующим образом изменить свой код. Так:

usleep(1000000) // generates 1 second delay
person Moin Syed    schedule 26.06.2020