Utilizzare gli Interval Timer in C su Linux

Gli interval timer sono uno strumento potente nella programmazione di sistema Linux, permettendo l’esecuzione periodica o ritardata di operazioni. In questo articolo, esploreremo come implementarli in C, focalizzandoci sulla funzione setitimer()
e sulle alternative moderne.
Cosa Sono gli Interval Timer?
Un interval timer è un meccanismo che genera un segnale dopo un intervallo specificato. È ideale per attività come:
- Monitoraggio delle prestazioni
- Esecuzione di task periodici
- Timeout di operazioni I/O
Configurare un Timer con setitimer()
La funzione setitimer()
definita in <sys/time.h>
consente di impostare timer basati su tre tipologie:
int setitimer(int type, const struct itimerval *new_value, struct itimerval *old_value);
- type: Specifica il tipo di timer (es.
ITIMER_REAL
). - new_value: Struttura che definisce l’intervallo iniziale e quello successivo.
- old_value: Opzionale; memorizza lo stato precedente del timer.
Tipologie di Timer
- ITIMER_REAL: Misura il tempo reale (es. cronometro), inviando
SIGALRM
. - ITIMER_VIRTUAL: Timer attivo solo durante l’esecuzione del processo, genera
SIGVTALRM
. - ITIMER_PROF: Misura il tempo di CPU (processo + system call), emette
SIGPROF
.
Esempio Pratico
Ecco un esempio che imposta un timer di 2 secondi, seguito da intervalli di 1 secondo:
#include <stdio.h>
#include <sys/time.h>
#include <signal.h>
void gestore_segnale(int sig) {
printf("Segnale %d ricevuto!\n", sig);
}
int main() {
struct itimerval timer;
// Configura intervallo iniziale a 2 secondi
timer.it_value.tv_sec = 2;
timer.it_value.tv_usec = 0;
// Intervallo successivo a 1 secondo
timer.it_interval.tv_sec = 1;
timer.it_interval.tv_usec = 0;
// Registra il gestore per SIGALRM
signal(SIGALRM, gestore_segnale);
// Avvia il timer in tempo reale
if (setitimer(ITIMER_REAL, &timer, NULL) == -1) {
perror("Errore nell'impostazione del timer");
return 1;
}
// Mantiene il processo attivo
while(1) {
pause();
}
return 0;
}
Spiegazione:
it_value
: Ritardo iniziale prima del primo segnale.it_interval
: Intervallo tra i segnali successivi.signal()
associa il gestoregestore_segnale
aSIGALRM
.
Gestione dei Segnali
La funzione gestore_segnale
intercetta SIGALRM
. È essenziale evitare operazioni non rientranti (es. printf
) nel gestore; per semplicità, qui usiamo printf
a scopo dimostrativo.
Limitazioni di setitimer()
- Obsolescenza: Sostituito da API POSIX più flessibili.
- Singolo timer per tipo: Non permette più timer dello stesso tipo.
- Interferenza con altre funzioni: Alcune librerie usano
SIGALRM
internamente.
Alternative Moderne
timer_create()
:
Crea timer multipli con segnali o thread dedicati (es.SIGEV_THREAD
).
#include <time.h>
int timer_create(clockid_t clockid, struct sigevent *sevp, timer_t *timerid);
timerfd_create()
:
Integra timer con file descriptor, ideale per event loop (es.epoll
).
#include <sys/timerfd.h>
int timerfd_create(int clockid, int flags);
Conclusioni
Gli interval timer sono utili per task periodici, ma setitimer()
è oggi considerato obsoleto. Per nuove applicazioni, preferire timer_create()
o timerfd_create()
, che offrono maggiore controllo e compatibilità. Sperimentate con gli esempi forniti ed esplorate le alternative per scenari complessi!
Approfondimenti: