I'm developing the game server, which is written on C. And I need to develop a cycle with a certain frequency (50 times per second)
to perform an algorithm.
The problem is that I can't pause the program for an exact time interval - 20000 microseconds.
Function usleep(20000)
runs about 30000 microseconds.
The result is always more on 10000 microseconds than expected.
Here is my simple example of code:
#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;
}
And the result of it's running:
$ ./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
I also tried to use function select()
, but result is the same as with the sleep()
.
Explain to me, please, what's wrong with my code.
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
Instead of sleeping for 20000 useconds, sleep for the time left till you want to run again, based on the call to clock_gettime
I.e:
usleep( lasttime+20000-now ); // But make sure you don't sleep when the result is negative
It is not that your code has a problem, but the actual call to sleep, reading the time, etc. takes time, and the system can't sleep for the exact time anyway unless it is a multiple of its exact clock cycle