|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
[C] Timer periodico
Ciao a tutti,
nel nostro programma abbiamo bisogno di timer che scadano ad orari prestabiliti (per esempio la mezzanotte o le 3 del mattino) per inviare messaggi verso l'esterno. Siamo su Linux e l'unico modo a me noto è di creare un thread con dentro un select() con il campo timeout settato a ora X - ora di adesso (quindi se ora sono le 18:14 la select dovrà durare circa 5 ore e 46 minuti) quando il timer scade facciamo le nostre cose e lo facciamo ripartire finché a Marzo alle 2 di notte scatta l'ora legale / solare e d'improvviso la mia select() non dovrebbe durare più 24 ore, ma 25 o 23! Se scatta alla una (il giorno dopo poi scatterà di nuovo alle 24 visto che ricalcola il tempo) potrebbe non essere tanto grave, ma se scatta alle 23 credendo che siano le 24 e poi di nuovo un ora dopo allora è male! Insomma il funzionamento che vorrei è come quelle di una sveglia se la setto per suonare alle 8 del mattino e poi porto l'ora avanti suona alle 8 (anche se in realtà sono le 7) posso ottenere lo stesso con un PC da migliaia di dollari? Linux sa per certo che c'è il DST l'orologio suo cambia (non solo quello della GUI, ma anche con il comando date) come posso ricevere un evento anche io? C'è un modo per avere la funzionalità "sveglia" in Linux? Grazie dell'aiuto! P.S. quello delle 3 del mattino è ancora più satanico visto che è per mettere l'ora giusta ad una povera stampante da 4 soldi che non ha il concetto di DST... peccato quella è l'ora X e quindi lo sbagliamo sempre quel timer
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: May 2001
Messaggi: 12936
|
Prova a dare un'occhiata alle funzioni timer_create e timer_settime.
http://man7.org/linux/man-pages/man2..._create.2.html http://man7.org/linux/man-pages/man2...settime.2.html Assicurati di usare CLOCK_MONOTONIC_RAW quale base del clock, in questo modo non dovresti avere problemi di cambio orario by sysadmin o NTP. Ultima modifica di WarDuck : 29-11-2015 alle 20:33. |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
OK domani provo a giocarci un po'!
Per essere chiaro io voglio che se l'oravenga cambiato il timer cambi... quindi non è mi chiara molto la nota su CLOCK_MONOTONIC_RAW. Il mio timer deve scattare alle 24:00:00 tra 3:22:00 ore o tra 21 minuti se sposto l'orologio di sistema avanti di 2 ore! Mi preoccupa un po' il fatto che si basi sui segnali visto che interrompono un po' il flusso dell'applicazione (è uno dei rari casi in cui il C non è più procedurale!) avevo però visto che c'era un modo per attendere un segnale in una select... così manterrei il main dei thread timer relativamente simile a come è adesso... Ultima modifica di fano : 29-11-2015 alle 21:42. |
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: May 2001
Messaggi: 12936
|
Quote:
Per cui se in un certo istante il counter è a 1000 e imposti il timer per scattare a 1000+X, indipedentemente dall'ora di sistema lui dovrebbe scattare quando il counter raggiungerà il valore 1000+X. Comunque è una questione interessante, domani se ho tempo provo anche io PS: in merito ai segnali credo che tu possa scegliere come fare il delivery dell'evento. |
|
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
Allora ho finalmente risolto il problema (o quasi): la buona notizia è che timer_create() permette di creare 2 tipi di timer:
Visto che timer_settime() supporta la possibilità di ripetere periodicamente anche il timer ne ho ricavato facilmente un III tipo: Timer Periodico. Quindi posso creare un timer per le 00:00:00 e poi spostare l'orologio della macchina con il comando date alle 23:59:59 e vederlo scattare dopo un secondo? Sì funziona come un cavallo E se scatta l'ora legale dura un'ora in più? Assolutamente! Restava un problema come detto sopra noi non volevamo realmente i segnali, visto l'imprendicibilità che hanno su quale thread vengono eseguiti fortunatamente se ne sono resi conto anche loro e quindi un timer può essere anche notificato in un thread ovvero allo scadere di ogni timer un nuovo thread viene creato (dal Kernel) e la callback fornita viene chiamata. Un po' un kludge come tanti che sono dentro le API C di Linux, ma sembra funzionare... per ora Possibili difetti:
Ah detesto profondamente come il C rappresenta il tempo: http://pubs.opengroup.org/onlinepubs...sh/time.h.html time_t, struct tm, struct timespec, 5 o 6 orologi (CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_???). Un problema resta: l'ora legale è un limite satanico che non può essere traversato per esempio io posso fare un timer fino alla notte in cui le 2 di notte diventano le 3, ma ho fatto una scoperta aberrante le 2 di notte avvengono 2 volte quella notte L'implementazione attuale è un po' farlocca quando l'ora è solare c'è tutte le notte un timer fino alle 3.00 che quando scade verifica se, in realtà, sono le 2.00 e allora va a menarlo alla povera stampante che chissà perché pretende di avere un orologio, ma, poi, non sa gestire il DST, quando l'ora è legale il timer diventa tutte le notti alle 2.00. Ma ciò che vorremmo veramente sapere è "se ora c'è l'ora solare quando dovrà essere cambiata nell'ora legale?" e allora solo "in quei giorni" (sembra una pubblicità dei salva-slip detta così ) settare il nostro timer ovvero per solo 2 volte all'anno.Una possibile soluzione sarebbe di parsarsi il file in /etc/timezone/xxx e leggersi da lì quando sono "quei giorni" anche se preferirei che il kernel mi avvisasse in qualche modo con un evento... Ultima modifica di fano : 05-12-2015 alle 21:30. |
|
|
|
|
|
#6 |
|
Moderatore
Iscritto dal: Nov 2006
Messaggi: 21964
|
non fai prima a creare il tuo programma che cambia solamente l'ora e far gestire il lancio del programma direttamente al sistema operativo mediante cron ?
__________________
"WS" (p280,cx750m,4790k+212evo,z97pro,4x8GB ddr3 1600c11,GTX760-DC2OC,MZ-7TE500, WD20EFRX) Desktop (three hundred,650gq,3800x+nh-u14s ,x570 arous elite,2x16GB ddr4 3200c16, rx5600xt pulse P5 1TB)+NB: Lenovo p53 i7-9750H,64GB DDR4,2x1TB SSD, T1000 |
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
No, non posso usare Crontab l'applicazione deve fare altre cose nel momento del cambio dell'ora legale / solare oltre a settare l'ora alla stampante e un programma esterno non potrebbe certo accedere alle sue variabili esterne.
Devo quindi trovare un modo per cui capisca da solo quando si deve cambiare l'ora legale / solare al limite mi parserò quel file mi scoccia un po' perché duplico il lavoro che Linux sta già facendo, ma se, davvero, non c'è modo per essere informato di questo evento... |
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Ma è proprio necessario che siano le 3 in punto? Non potresti aspettare 1 o 2 secondi dopo le 3, di modo che sia sicuro che il cambio dell'ora sia già avvenuto?
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: Apr 2005
Messaggi: 3285
|
Quote:
In cron ti metti uno script che lancia un signal al tuo programma , tipo un SIGUSR1. E se proprio non vuoi duplicare troppo puoi gestirlo anche solo per la gestione dell'ora legale. |
|
|
|
|
|
|
#10 | |
|
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
Quote:
@Kaya Quindi anche la soluzione del segnale non è possibile a quale processo lo manderei? L'intelligenza, purtroppo deve rimanere all'interno dell'applicazione distribuita... |
|
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Allora verifica periodicamente, ogni secondo o anche meno se ti è possibile, l'orario corrente. Conserva il precedente e controlla, quando scatta il nuovo evento, se la differenza fra l'attuale e il precedente è negativa (perché il problema si pone solo quando l'orologio torna indietro, immagino) e di gran lunga più elevata rispetto a ciò che ti aspetti normalmente. A questo punto dovresti essere relativamente sicuro di aver beccato proprio il cambio, e propaghi la notizia a tutti i dispositivi.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
se hai un kernel relativamente recente puoi ottenere la notifica del cambio dell'ora (personalmente non l'ho testata, YMMV):
https://lkml.org/lkml/2010/9/16/405
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele |
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
Questa time_change_notify() sembra proprio quello che sto cercando, purtroppo il mio kernel è vecchissimo (2.6.18 del 2009!), quindi mi sa che non c'è la cosa strana è che anche su un kernel 4.0 non la trovo (non c'è nessun man e in /usr/include non trovo la definizione).
Vedo però che l'esempio postato la chiama attraverso una syscall quindi ho ancora una flebile speranza... devo provare a compilarlo |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 12:54.



















