The standard way to get a regular beat in linux (or any UNIX for that matter) is to use setitimer (2):
#include <sys/time.h> #include <signal.h> struct itimerval timer; timer.it_interval.tv_sec = timer.it_value.tv_sec = 0; timer.it_interval.tv_usec = timer.it_value.tv_usec = 1000; /* 1000 microseconds */ if (setitimer(ITIMER_REAL, &timer, 0) < 0) { perror("setitimer"); exit(1); }
Now you get a SIGALRM signal every milliseconds, so you start the loop with sigwait :
sigset_t alarm_sig; int signum; sigemptyset(&alarm_sig); sigaddset(&alarm_sig, SIGALRM); while (1) { sigwait(&alarm_sig, &signum); ... do your stuff to send a packet, or whatever. }
Now you will send a packet every milliseconds, LONG LAST, AS THE SYSTEM MAY BE COMPLETED. The latter is important - if the system is too heavily loaded (or your code to create the package is too slow), the next signal will come before the next sigwait call and kill your process. If you do not want this, set the signal for SIGALARM signals:
void missed_alarm(int signum) { write(2, "Missed Alarm!\n", 14); } signal(SIGALRM, missed_alarm);
Now, if an alarm is skipped, your packets will be slowed down (you skip the slot), but you will get a message about this on stderr.
One major problem with the above is that it depends on the resolution of your system timer. On Linux, this is highly dependent on the CONFIG_HIGH_RES_TIMERS kernel configuration. If this is not enabled, you will probably only have a resolution of 10 ms, so trying to use a 1 ms clock will not succeed. I believe that it is enabled by default for most x86_64 distributions, but you can check by looking at / proc / timer _list and see what the resolution of the "ktime_get_real" clock is.