Share

Utilizzare gli Interval Timer in C su Linux

interval-c-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

  1. ITIMER_REAL: Misura il tempo reale (es. cronometro), inviando SIGALRM.
  2. ITIMER_VIRTUAL: Timer attivo solo durante l’esecuzione del processo, genera SIGVTALRM.
  3. 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 gestore gestore_segnale a SIGALRM.

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

  1. 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);
  1. 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:

Potrebbe interessarti