在linux(或任何UNIX)上获得重复常规心跳类型的标准方法是使用setitimer(2):
#include
#include
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); }
现在,您将每毫秒获得一个SIGALRM信号,因此您使用sigwait调用运行循环:
sigset_t alarm_sig;
int signum;
sigemptyset(&alarm_sig);
sigaddset(&alarm_sig, SIGALRM);
while (1) {
sigwait(&alarm_sig, &signum); /* wait until the next signal */
... do your stuff to send a packet, or whatever.
}
现在你将每毫秒发送一个数据包,因为系统可以保持这种状态.后者很重要 – 如果系统负载过重(或者您创建数据包的代码太慢),下一个信号将在下一个sigwait调用之前进入并终止您的进程.如果您不想这样,请为SIGALARM信号输入信号处理程序:
void missed_alarm(int signum) {
/* we missed a timer signal, so won't be sending packets fast enough!!! */
write(2, "Missed Alarm!\n", 14); /* can't use printf in a signal handler */
}
signal(SIGALRM, missed_alarm);
现在,如果错过了一个警报,你的数据包发送将会变慢(你会错过一个插槽),但是你会在stderr上收到有关它的消息.
上面的一个重要问题是它取决于您的系统计时器分辨率.在Linux上,这在很大程度上取决于内核配置CONFIG_HIGH_RES_TIMERS.如果未启用,则可能只有10ms的分辨率,因此尝试使用1ms时钟将会严重失败.我相信它在大多数x86_64发行版上默认启用,但您可以通过查看/ proc / timer_list来查看,看看’ktime_get_real’时钟的分辨率是多少.