View Full Version : [C++] Timer che funziona in background
Salve a tutti
Sto scrivendo un programma in C su Linux (non sono molto esperto, quindi lo faccio in modo molto spartano) e avrei bisogno di un timer che agisce in background (quindi nel frattempo il programma principale continua a girare) e che ad intervalli prestabiliti mi faccia eseguire delle funzioni, dopodichè torna al programma principale fino alla nuova chiamata.
Per windows ho una funzione che però usa librerie windows.h, mentre io ho bisogno di implementarlo in Linux.
Penso che non vadano bene le funzioni sleep, e meno che non riesca a farle eseguire in un thread in background ma non saprei come fare.
Se qualcuno può aiutarmi grazie mille!
ilsensine
26-09-2007, 11:37
Puoi usare obrobri tipo alarm o setitimer, ma io risolverei con un veloce thread dedicato.
grazie
Un thread dedicato in cosa consisterebbe e come andrebbe implementato?
Scusa ma non sono molto pratico e non so proprio da dove partire!
Soprattutto è un metodo sicuro?
Non ho bisogno di una precisione al microsecondo, ma una cosa che ogni es. 2 minuti (ripeto non importa un millisecondo in più o in meno, però deve partire) mi fa eseguire una serie di funzioni sui dati acquisiti (e messi in variabili) dal programma principale nel frattempo
grazie di nuovo
ilsensine
26-09-2007, 11:56
Non sai cosa sono i thread? Non posso spiegartelo in due righe...
Usa alarm allora, con i thread dovresti gestire eventuali problemi di concorrenza. Se non conosci i thread tantomeno conosci i problemi connessi.
trallallero
26-09-2007, 12:32
scusa ma se il programma e´ semplice ti basta chiamare una funzione ad ogni fine o inizio main loop e controllare se il tempo passato e´ >= 2 minuti allora esegui quello che ti serve e resetti il timer senno` fai niente.
trallallero
26-09-2007, 12:42
Puoi usare obrobri tipo alarm o setitimer
perche´ obrobri ?
scusa ma se il programma e´ semplice ti basta chiamare una funzione ad ogni fine o inizio main loop e controllare se il tempo passato e´ >= 2 minuti allora esegui quello che ti serve e resetti il timer senno` fai niente.
Avevo pensato ad una cosa del genere ma come faccio a vedere quanto tempo è passato?Leggendo l'orologio di sistema?
Inoltre il main loop sta fermo in attesa di leggere da seriale ed a questo punto fa un ciclo, quindi non è detto che possa controllare con continuità il tempo trascorso. Eventualmente dovrei impostare dei timeout della seriale ma preferirei evitarlo.
Sarebbe meglio avere delle chiamate periodiche indipendente dal main.
Scusate se non mi spiego con linguaggio corretto ma di informatica ho dato solo un esame al primo anno di ingegneria!
Per ora sto provando a capire come funziona alarm, grazie per i consigli!
ciao
ilsensine
26-09-2007, 13:14
perche´ obrobri ?
Peché usano degli obrobri (i segnali).
trallallero
26-09-2007, 14:32
Avevo pensato ad una cosa del genere ma come faccio a vedere quanto tempo è passato?Leggendo l'orologio di sistema?
Inoltre il main loop sta fermo in attesa di leggere da seriale ed a questo punto fa un ciclo, quindi non è detto che possa controllare con continuità il tempo trascorso. Eventualmente dovrei impostare dei timeout della seriale ma preferirei evitarlo.
Sarebbe meglio avere delle chiamate periodiche indipendente dal main.
Scusate se non mi spiego con linguaggio corretto ma di informatica ho dato solo un esame al primo anno di ingegneria!
Per ora sto provando a capire come funziona alarm, grazie per i consigli!
ciao
proprio perche´ sei alle prime armi ti dico di fare una funzione semplice.
Per esempio questo programma stampa "Time To" e ritorna 1 ogni 5 secondi, altrimenti ritorna 0.
Il tutto dentro un loop "ultrasleepato" nel senso che fai una usleep per non impiegare tutte le risorse ma senza rallentarlo troppo (tipo con una sleep).
#include <stdio.h>
#include <time.h>
int IsTimeTo()
{
static time_t Time = 0;
if (time(NULL) - Time >= 5)
{
Time = time(NULL);
puts( "Time To" );
return 1;
}
return 0;
}
int main(int argc, char* argv[])
{
while(1)
{
IsTimeTo();
usleep(2000);
}
}
ovviamente non lo puoi usare se usi una read senza O_NONBLOCK (cioe´ devi leggere senza bloccare)
si grazie, per ora penso che adotterò questa soluzione.
Nella read ho il O_NONBLOCK, però i devo vedere come impostare i timeout della seriale perchè fino ad ora erano ad attesa infinita.
Poi vedrò come andrà nel programma finale e quali errori di temporizzazione mi comporta (che più o meno sarà al massimo del tempo di un loop, ma non so questo di che ordine sia)
Non sai cosa sono i thread? Non posso spiegartelo in due righe... ti sfido :D
ecco la mia spiegazione:
@PoliX: un programma può essere costituito da più parti che girano contemporaneamente: si chiamano thread. su Linux per eseguire una funzione contemporaneamente al resto del programma puoi usare la funzione pthread_create (http://www.linuxmanpages.com/man3/pthread_create.3thr.php).
una riga virgola 6 sul mio monitor (1280x1024), prova a far di meglio :asd:
Peché usano degli obrobri (i segnali).
HA-HA!! allora lo ammettete anche voi :Prrr:
questa devo dire che mi coglie alla sprovvista :D
ilsensine
27-09-2007, 08:47
HA-HA!! allora lo ammettete anche voi :Prrr:
questa devo dire che mi coglie alla sprovvista :D
I segnali sono indispensabili in alcuni casi (ad es. SIGSEGV, SIGILL, ...), ma nel tempo se ne è veramente abusato (v. ad es. dnotify).
Ultimamente è stata sviluppata una nuova interfaccia, finalmente decente, per la gestione dei segnali (signalfd).
ilsensine
27-09-2007, 08:49
ti sfido :D
ecco la mia spiegazione:
@PoliX: un programma può essere costituito da più parti che girano contemporaneamente: si chiamano thread. su Linux per eseguire una funzione contemporaneamente al resto del programma puoi usare la funzione pthread_create (http://www.linuxmanpages.com/man3/pthread_create.3thr.php).
una riga virgola 6 sul mio monitor (1280x1024), prova a far di meglio :asd:
Spero che non segua la tua sintetica descrizione, si ritroverebbe in un mare di guai :cool:
Non puoi parlare dei thread senza parlare dei problemi di concorrenza ;)
I segnali sono indispensabili in alcuni casi (ad es. SIGSEGV, SIGILL, ...), ma nel tempo se ne è veramente abusato (v. ad es. dnotify). se fa schifo uno fanno schifo tutti: io trovo assurdo che un thread di punto in bianco debba eseguire una cosa completamente diversa e che il suo stack a partire da un certo punto contenga frames che non ci azzeccano nulla con quelli precedenti (magari oltrettutto con un frame interrotto a metà). una feature o ci sta o non ci sta, e quando ci sta rassegnati all'idea che tutti la usano, senza compromessi. è la stessa cosa che succede nei linguaggi di programmazione, è il motivo percui PGI-Bis conduce la sua strenua battaglia contro le closures nel Java e a favore della filosofia POJO. :D
Spero che non segua la tua sintetica descrizione, si ritroverebbe in un mare di guai :cool:
Non puoi parlare dei thread senza parlare dei problemi di concorrenza ;) ho affidato tutto alla sua ragione :P
:boxe: LUNGA VITA AI POJO! :boxe:
ilsensine
27-09-2007, 13:37
se fa schifo uno fanno schifo tutti: io trovo assurdo che un thread di punto in bianco debba eseguire una cosa completamente diversa e che il suo stack a partire da un certo punto contenga frames che non ci azzeccano nulla con quelli precedenti (magari oltrettutto con un frame interrotto a metà). una feature o ci sta o non ci sta, e quando ci sta rassegnati all'idea che tutti la usano, senza compromessi. è la stessa cosa che succede nei linguaggi di programmazione, è il motivo percui PGI-Bis conduce la sua strenua battaglia contro le closures nel Java e a favore della filosofia POJO. :D
No, lo scopo dei segnali - originariamente - era proprio quello: gestire una cosa "completamente diversa", dove il programma poteva essere benissimo andato a puttane (ad esempio perché il processo è andato...in segmentation fault, fornendo l'estrema possibilità di eseguire codice per generare ad es. un backtrace). Anche SIGILL può prestarsi a interessanti usi (ad es. emulazione in userspace di istruzioni assembler non supportate).
Tutti gli altri usi che se ne sono fatti sono dovuti a limitazioni dei sistemi unix, che non fornivano alternative su come fare certe cose. Oggi le alternative ci sono, e i segnali possono benissimo essere abbandonati, ad eccezione di quelli fatali (SEGV, ILL, e simili). Almeno su linux.
No, lo scopo dei segnali - originariamente - era proprio quello: gestire una cosa "completamente diversa", dove il programma poteva essere benissimo andato a puttane (ad esempio perché il processo è andato...in segmentation fault, fornendo l'estrema possibilità di eseguire codice per generare ad es. un backtrace). se per "backtrace" intendi un dump allora preferisco un tipo di approccio completamente diverso: tra un sistema operativo con DrWtsn32.exe e un sistema operativo coi segnali preferisco 1000 volte la prima :Prrr:
non per altro ma perché se poi su quel sistema operativo io ci devo programmare per studio ed in futuro per lavoro, allora preferisco non aver nulla a che fare coi segnali :D
Anche SIGILL può prestarsi a interessanti usi (ad es. emulazione in userspace di istruzioni assembler non supportate). a mio parere questa non è una argomentazione sufficiente a giustificare un design come quello dei segnali: su Windows esistono le eccezioni, non potevano fare qualcosa del genere? non è che segnali ed eccezioni siano due cose tanto differenti alla fine, solo che la seconda ha il pregio di mantenere uno stato di coerenza nello stack.
ilsensine
28-09-2007, 08:46
se per "backtrace" intendi un dump allora preferisco un tipo di approccio completamente diverso: tra un sistema operativo con DrWtsn32.exe e un sistema operativo coi segnali preferisco 1000 volte la prima :Prrr:
non per altro ma perché se poi su quel sistema operativo io ci devo programmare per studio ed in futuro per lavoro, allora preferisco non aver nulla a che fare coi segnali :D
a mio parere questa non è una argomentazione sufficiente a giustificare un design come quello dei segnali: su Windows esistono le eccezioni, non potevano fare qualcosa del genere? non è che segnali ed eccezioni siano due cose tanto differenti alla fine, solo che la seconda ha il pregio di mantenere uno stato di coerenza nello stack.
I segnali sono un design nato quando Bill Gates ancora aveva il ciuccio, come fai a paragonarli con ciò che hai a disposizione su windows lo sai solo tu.
Ovvio che _oggi_ ti sembrano obsoleti, e non mi sembra che li sto difendendo.
trallallero
28-09-2007, 08:57
a mio parere questa non è una argomentazione sufficiente a giustificare un design come quello dei segnali: su Windows esistono le eccezioni, non potevano fare qualcosa del genere? non è che segnali ed eccezioni siano due cose tanto differenti alla fine, solo che la seconda ha il pregio di mantenere uno stato di coerenza nello stack.
ma, se non sbaglio, la stessa HotMail (MS) usa un server Unix che usa gli abominevoli segnali :fiufiu:
ilsensine
28-09-2007, 08:59
ma, se non sbaglio, la stessa HotMail (MS) usa un server Unix che usa gli abominevoli segnali :fiufiu:
No li usavano in passato (server BSD se non ricordo male).
E non lanciamo il messaggio che "unix" = "segnali"...ormai sono poco usati.
ilsensine
28-09-2007, 09:53
non è che segnali ed eccezioni siano due cose tanto differenti alla fine, solo che la seconda ha il pregio di mantenere uno stato di coerenza nello stack.
\me gnurant
Mi spieghi cosa combinano le eccezioni di windows con lo stack? Che intendi con "coerenza dello stack"?
Allora, grazie per i consigli ma penso che non impareò i thread :)
Ho provato con la soluzione di trallallero ma mi si incasina nell'attesa di leggere da seriale (non posso o non sono capace io di avere l'opzione "o ci sono i 21 byte da leggere con la read oppure fai un altro ciclo", cioè io riesco solo a leggere 1 byte alla volta se non voglio bloccare la read)
Sto provando con setitimer e i (da voi) tanto odiati segnali :D , ditemi se a grandi linee queste cose sono giuste:
Nel main
{
...
struct itimerval timer;
...
signal (SIGALRM , handler);
...
//metto i valori che voglio in timer
...
setitimer (ITIMER_REAL , &timer , NULL);
...
while(1)
{
//il mio ciclo
}
...
}
Fuori dal main
void handler(int a)
{
//le mie operazioni da fare ad ogni intervallo
...
signal ( SIGALRM , handler);
}
Mi chiedo se dentro handler (chiamata quando arriva il segnale) posso fare qualunque operazione, per esempio chiamare altre funzioni presenti su altri file sorgente (come faccio tranquillamente dal main).
Inoltre i segnali arrivano anche quando il programma sta svolgendo altre funzioni esterne al main?
Un altra cosa (su cui spero di non aver preso una cantonata) è la possibilità di bloccare l'arrivo dei segnali, cosa che dovrei fare quando il programma svolge determinate funzioni che non devono essere interrotte.
Mi sembra di aver capito di dover fare così:
All'interno della funzione che non deve subire interruzioni
{
...
sigset_t blocchi;
sigempty(&blocchi);
sigaddset(&blocchi , SIGALRM);
sigprocmask(SIG_BLOCK , &blocchi , NULL);
...
// operazioni che non vengono interrotte da SIGALRM
...
sigprocmask(SIG_UNBLOCK , &blocchi, NULL);
}
Domanda:un eventuale segnale arrivato durante il blocco viene ricordato e fa eseguire l'handler dopo lo sblocco?
Scusate se per voi sono banalità, ma io sono un telecomunicazioni e non un informatico:rolleyes:
ciao a tutti
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.