Вы должны использовать settimer
int setitimer(int which, const struct itimerval *value,
struct itimerval *ovalue);
Просто поместите код, который вы хотите выполнять каждые 400 мс, в обработчик SIGALRM. Таким образом, вам не нужно учитывать время, затрачиваемое на выполнение вашего кода, которое может измениться. Я не уверен, что произойдет, если обработчик сигнала не вернется до того, как генерируется следующий сигнал.
Схема того, как может выглядеть часть кода, показана ниже.
void periodic_fuc(int signal_num)
{
...
signam(SIGALRM, periodic_func);
}
int main(...)
{
struct itimerval timerval = {0};
signal(SIGALRM, periodic_func);
...
timerval.it_interval.tv_usec = 400000;
timerval.it_value.tv_usec = 400000; // Wait 400ms for first trigger
settimer(ITIMER_REAL, &timerval, NULL);
while (!exit)
sleep(1);
return 0;
}