2012-06-28 6 views
5

Molto tempo fa ho avuto un bug nel mio programma. La causa principale è che la funzione CDo timer hanno una migliore precisione rispetto al sonno()

sleep(60); 

farebbe in rare occasioni dormono meno di 60 secondi. O la funzione ha fatto sì che il filo a dormire più di 60 s, ma l'orologio è stato cambiato automaticamente dal sistema operativo (questo sembra probabile dal momento bug stava accadendo solo su XX::00::00), alias esso si manifestava raramente, e solo su "ora rotonda" (sleep shoudl si è concluso a> xh0m0s, è terminato su x-1h59m59.99*s).
Quindi il mio project manager ha continuato a parlare di come ha detto milioni di volte che dovremmo usare solo timer, non dormire. Da quel momento ho accettato l'idea che i timer siano più accurati di sleep(), ma ora sento che dovrei chiedere una fonte più autorevole. Quindi:

  1. I timer sono più precisi del sonno?
  2. (relativi) sono essi in fondo (a livello di sistema operativo) implementata con metodi diversi?
    So timer sono usati per fare callback, dormire ritarda solo l'esecuzione di thread corrente, Im parlando di parte l'esecuzione ritardo della realizzazione.

BTW OS era Linux, ma mi interessa la risposta generale se possibile.

+0

In entrambi i casi, non è una buona idea aspettarsi che un'operazione di timer/sospensione si interrompa veramente per la durata specificata. Il sistema operativo fa tutto il possibile per onorare la tua richiesta, ma a volte fallirà. Preparati per questo. – TheZ

+0

So che ora, bug "fix" (dopo che il manager si è calmato dai suoi timer rant) era solo per aggiungere un po 'di ritardo alla sicurezza. – NoSenseEtAl

+11

Sembra che ci sia un problema architettonico più profondo se una differenza di +/- 1 secondo in un sonno fa sì che tutto si rompa ... – Rook

risposta

2

Non esiste una risposta generale per il semplice motivo che non esiste nulla nello standard C o C++ che fornisce la possibilità di mettere un'applicazione in stato di sospensione. Quindi la discussione sarà intrinsecamente dipendente dal sistema operativo.

La funzione unix sleep() ha una granulosità grossolana. Ci sono anche usleep() e nanosleep() che hanno granularità molto più fine. La funzione select() può anche essere utilizzata per mettere un'applicazione in stop. Basta specificare un timeout e nessun descrittore di file.

Nota 1: l'interazione tra sleep(), usleep(), nanosleep(), itimeri e allarmi non è specificata.

Nota # 2: non aspettatevi che nessuno di questi meccanismi abbia la precisione di un orologio atomico.

3

I timer sono decisamente più precisi del sonno. Il sonno è solo una misura approssimativa di quanto tempo prima che l'utilità di pianificazione riattivi un thread o un processo. Le modifiche all'orologio di sistema, un programmatore di attività sovraccarico, ecc. Influenzeranno il tempo di sospensione del sonno.

Un timer misurerà il tempo in modo più preciso. In generale un timer misurerà il tempo in modo accurato. Esistono due tipi di timer: quelli basati sull'orologio di sistema come le funzioni in "time.h". Quelli saranno interessati da cose come le modifiche all'orologio di sistema. Ad esempio, se si modifica l'ora del sistema, si passa dall'ora legale o si sospende la macchina, ecc. Il tempo misurato effettivo potrebbe essere diverso dal tempo reale.

Gli altri tipi di clock sono timer ad alta risoluzione basati sui tick della CPU. Questi sono timer come QueryPerformanceTimer su windows e clock_gettime() su linux. Questi semplicemente contano i cicli della CPU.Essi non saranno influenzati dai cambiamenti al timer di sistema - ma potranno deviare dal tempo del mondo reale in due modi:

  1. Il tempo ci inclinare per lunghi periodi perché la risoluzione di clock non è esatta tale che per lunghi periodi di misurazione il tempo in questo modo causerà la deriva del tempo della CPU dal tempo reale.
  2. Se la macchina è sospesa, la CPU si arresta e il timer non tiene conto di ciò.

Quello che vuoi fare è dormire per un tempo molto più breve e utilizzare l'orologio con la risoluzione appropriata. Per esempio. se hai bisogno di dormire per meno di qualche minuto, dovresti usare timer ad alta risoluzione. Dormi 100 volte più spesso del necessario e controlla il tempo trascorso ogni volta che il sonno ritorna per vedere se è trascorso il giusto tempo. Se hai bisogno di dormire per più di qualche minuto fai lo stesso ma con le funzioni in time.h per controllare il tempo trascorso.

Se è necessario essere accurati al 100% con il tempo, potrebbe essere necessario un hardware specializzato o controllare periodicamente in tempo reale un server orario online, ad esempio l'orologio atomico della marina. (http://tycho.usno.navy.mil/ntp.html)