2010-08-19 14 views
136

Puoi spiegare la differenza tra CLOCK_REALTIME e CLOCK_MONOTONIC gli orologi restituiti da clock_gettime() su Linux?Differenza tra CLOCK_REALTIME e CLOCK_MONOTONIC?

Quale è una scelta migliore se ho bisogno di calcolare il tempo trascorso tra i timestamp prodotti da una fonte esterna e l'ora corrente?

Infine, se un daemon NTP regola periodicamente l'ora di sistema, in che modo queste regolazioni interagiscono con ciascuna di CLOCK_REALTIME e CLOCK_MONOTONIC?

risposta

165

CLOCK_REALTIME rappresenta l'ipotesi migliore della macchina per l'attuale orologio da parete, ora del giorno. Come Ignacio e MarkR dire, questo significa che CLOCK_REALTIME può saltare avanti e indietro come l'orologio di ora del giorno del sistema viene modificato, anche da NTP.

CLOCK_MONOTONIC rappresenta il tempo assoluto di orologio a muro trascorso da un punto fisso arbitrario nel passato. Non è influenzato dai cambiamenti nell'orologio dell'ora del sistema.

Se si desidera calcolare il tempo trascorso tra due eventi osservati su una macchina senza un riavvio intermedio, CLOCK_MONOTONIC è l'opzione migliore.

+9

Nota che sui nuovi kernel è disponibile CLOCK_MONOTONIC_RAW che è ancora migliore (nessuna regolazione NTP). –

+12

@JosephGarvin per un certo valore di "migliore", forse - CLOCK_MONOTONIC_RAW può essere veloce o lento in tempo reale di diverse (o diverse centinaia) parti per milione e la sua velocità può variare a causa di condizioni ambientali come temperatura o voltaggio (o tempo di rubare su macchine virtuali). Su una macchina che funziona correttamente, NTP fa del suo meglio per mitigare tutti questi fattori e quindi CLOCK_MONOTONIC riflette più da vicino * true * il tempo trascorso. – hobbs

+16

Concesso, potrebbe essere interessante avere un CLOCK_MONOTONIC_PARBOILED che è stato influenzato dagli sforzi di NTP per correggere gli errori di frequenza, ma non è influenzato dai suoi sforzi per correggere gli errori di fase, ma questa è una grande complessità per un guadagno dubbio :) – hobbs

13

CLOCK_REALTIME è influenzato dall'NTP e può spostarsi avanti e indietro. CLOCK_MONOTONIC no, e avanza di un segno di spunta per tick.

+9

CLOCK_MONOTONIC è influenzata dalla regolazione del tempo di NTP (tempo di rotazione). Non salterà comunque. – derobert

+2

Ma sui kernel più recenti c'è CLOCK_MONOTONIC_RAW, che in realtà non è influenzato da NTP. –

+1

"tick" - qualsiasi idea approssimativa di come le istruzioni della CPU grande/lunga/alta siano un segno di spunta su Linux/amd64? O dove posso ottenere documenti su questo? – kevinarpe

13

Oltre a Ignacio's answer, CLOCK_REALTIME può andare avanti in avanti a salti e occasionalmente indietro. CLOCK_MONOTONIC non ne ha né; continua semplicemente ad andare avanti (anche se probabilmente si reimposta al riavvio).

Un'app robusta deve essere in grado di tollerare saltuariamente l'inoltro CLOCK_REALTIME in avanti (e forse all'indietro molto di rado ogni tanto, anche se questo è più di un caso limite).

Immaginate cosa succede quando si sospende il laptop - CLOCK_REALTIME salta in avanti dopo il curriculum, CLOCK_MONOTONIC no. Provalo su una VM.

+3

CLOCK_MONOTONIC inizia da 0 all'avvio del programma; non è per uso di interprocessi. – Benubird

+15

@Benubird: non inizia da 0 all'avvio del programma. Questo è 'CLOCK_PROCESS_CPUTIME_ID'. Test rapido: '$ perl -w -MTime :: HiRes = clock_gettime, CLOCK_MONOTONIC -E 'dire clock_gettime (CLOCK_MONOTONIC)'' -> 706724.117565279. Quel numero corrisponde al tempo di attività del sistema su Linux, ma lo standard dice che è arbitrario. – derobert

+4

Per inciso, non credo che il comportamento di Linux in cui 'CLOCK_MONOTONIC' si ferma su una sospensione/ripresa sia conforme a POSIX. Dovrebbe essere il tempo trascorso da un punto fisso nel passato, ma fermando l'orologio sopra sospendere/riprendere interrompe quello. – caf

27

del libro LINUX sistema di programmazione 2nd Edition Robert Love, affronta in modo specifico la tua domanda all'inizio del capitolo 11, pg 363:

L'aspetto importante di una fonte di tempo monotona non è il valore corrente , ma la garanzia che la fonte ora è strettamente linearmente aumentando, e quindi utile per calcolare la differenza di tempo tra due campionamenti

che sai d, credo che stia presupponendo che i processi stiano girando sulla stessa istanza di un sistema operativo, quindi potresti voler eseguire una calibrazione periodica per poter stimare la deriva.

2

POSIX 7 specifica sia a http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html:

CLOCK_REALTIME:

Questo orologio rappresenta l'orologio di misurazione in tempo reale per il sistema.Per questo orologio, i valori restituiti da clock_gettime() e specificati da clock_settime() rappresentano la quantità di tempo (in secondi e nanosecondi) dall'Epoch.

CLOCK_MONOTONIC (opzionale):

Per questo orologio, il valore restituito da clock_gettime() rappresenta la quantità di tempo (in secondi e nanosecondi) dal punto imprecisato in passato (ad esempio , tempo di avvio del sistema o Epoch). Questo punto non cambia dopo il tempo di avvio del sistema. Il valore dell'orologio CLOCK_MONOTONIC non può essere impostato tramite clock_settime().

clock_settime() dà un indizio importante: sistemi POSIX sono in grado di cambiare arbitrariamente CLOCK_REALITME con esso, in modo da non fare affidamento su di esso né che scorre continuamente, né in avanti. NTP potrebbe essere implementato utilizzando clock_settime() e potrebbe riguardare solo CLOCK_REALITME.

implementazione del kernel Linux sembra prendere il tempo di avvio come l'epoca per CLOCK_MONOTONIC: Starting point for CLOCK_MONOTONIC