2010-08-19 11 views
136

¿Podría explicar la diferencia entre CLOCK_REALTIME y CLOCK_MONOTONIC relojes devueltos por clock_gettime() en Linux?Diferencia entre CLOCK_REALTIME y CLOCK_MONOTONIC?

¿Cuál es una mejor opción si necesito calcular el tiempo transcurrido entre las marcas de tiempo producidas por una fuente externa y la hora actual?

Por último, si tengo un daemon NTP que ajusta periódicamente el tiempo del sistema, ¿cómo interactúan estos ajustes con cada uno de CLOCK_REALTIME y CLOCK_MONOTONIC?

Respuesta

165

CLOCK_REALTIME representa la mejor conjetura de la máquina en cuanto al reloj de pared actual, hora del día. Como dicen Ignacio y MarkR, esto significa que CLOCK_REALTIME puede saltar hacia adelante y hacia atrás a medida que se cambia el reloj del sistema de hora del día, incluido el NTP.

CLOCK_MONOTONIC representa el tiempo de reloj de pared absoluto transcurrido desde algún punto fijo arbitrario en el pasado. No se ve afectado por los cambios en el reloj del sistema de hora del día.

Si desea calcular el tiempo transcurrido entre dos eventos observados en una máquina sin un reinicio intermedio, CLOCK_MONOTONIC es la mejor opción.

+9

Tenga en cuenta que en los núcleos más nuevos, CLOCK_MONOTONIC_RAW está disponible, lo que es aún mejor (sin ajustes NTP). –

+12

@JosephGarvin, por algún valor de "mejor", quizás - CLOCK_MONOTONIC_RAW puede correr rápido o lento en tiempo real en varios (o varios cientos) partes por millón, y su velocidad puede variar debido a condiciones ambientales como temperatura o voltaje (o robar tiempo en máquinas virtuales). En una máquina que funciona correctamente, NTP hace todo lo posible para mitigar todos esos factores y, por lo tanto, CLOCK_MONOTONIC refleja más fielmente el * verdadero * tiempo transcurrido. – hobbs

+16

De acuerdo, podría ser interesante tener un CLOCK_MONOTONIC_PARBOILED afectado por los esfuerzos del NTP para corregir los errores de frecuencia, pero no afectado por sus esfuerzos para corregir errores de fase, pero eso es una gran complejidad para una ganancia dudosa :) – hobbs

13

CLOCK_REALTIME se ve afectado por NTP, y puede moverse hacia adelante y hacia atrás. CLOCK_MONOTONIC no lo es, y avanza con un tic por tick.

+9

CLOCK_MONOTONIC se ve afectado por el ajuste del tiempo de NTP (tiempo de giro). Sin embargo, no saltará. – derobert

+2

Pero en los núcleos más recientes hay CLOCK_MONOTONIC_RAW, que realmente no se ve afectado por NTP. –

+1

"tic" - ¿Alguna idea aproximada de cuán grande/larga/las instrucciones de la CPU son un tic en Linux/amd64? ¿O dónde puedo obtener documentos sobre esto? – kevinarpe

13

Además de Ignacio's answer, CLOCK_REALTIME puede avanzar hacia adelante en saltos, y ocasionalmente al revés. CLOCK_MONOTONIC no hace ninguno; simplemente sigue adelante (aunque probablemente se restablezca al reiniciar).

Una aplicación robusta debe ser capaz de tolerar CLOCK_REALTIME saltando hacia delante ocasionalmente (y tal vez hacia atrás muy levemente muy ocasionalmente, aunque eso es más una arista).

Imagínese lo que sucede cuando suspende su computadora portátil - CLOCK_REALTIME salta hacia delante siguiendo el currículum, CLOCK_MONOTONIC no. Pruébalo en una VM.

+3

CLOCK_MONOTONIC comienza en 0 cuando se inicia el programa; no es para uso interproceso. – Benubird

+15

@Benubird: No comienza en 0 cuando se inicia el programa. Eso es 'CLOCK_PROCESS_CPUTIME_ID'. Prueba rápida: '$ perl -w -MTime :: HiRes = clock_gettime, CLOCK_MONOTONIC -E 'dice clock_gettime (CLOCK_MONOTONIC)'' -> 706724.117565279. Ese número coincide con el tiempo de actividad del sistema en Linux, pero el estándar dice que es arbitrario. – derobert

+4

Como comentario aparte, no creo que el comportamiento de Linux donde 'CLOCK_MONOTONIC' se detiene sobre un suspender/reanudar sea POSIX-conforming. Se supone que es el momento desde un punto fijo en el pasado, pero detener el reloj durante suspender/reanudar eso. – caf

27

del libro sistema Linux segundo Programación Edición Robert Love, se refiere específicamente a su pregunta al comienzo del capítulo 11, página 363:

El aspecto importante de una fuente de tiempo monótona no es el valor actual , pero la garantía de que la fuente de tiempo es estrictamente lineal en aumento, y por lo tanto útil para el cálculo de la diferencia de tiempo entre dos muestreos

que Sai d, creo que está asumiendo que los procesos se están ejecutando en la misma instancia de un sistema operativo, por lo que es posible que desee ejecutar una calibración periódica para poder estimar la deriva.

2

POSIX 7 especifica tanto en http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html:

CLOCK_REALTIME:

Este reloj representa el reloj de medición en tiempo real para el sistema.Para este reloj, los valores devueltos por clock_gettime() y especificados por clock_settime() representan la cantidad de tiempo (en segundos y nanosegundos) desde la Época.

CLOCK_MONOTONIC (característica opcional):

Para este reloj, el valor devuelto por clock_gettime() representa la cantidad de tiempo (en segundos y nanosegundos) desde un punto no especificado en el pasado (por ejemplo , el tiempo de inicio del sistema o la Época). Este punto no cambia después del tiempo de inicio del sistema. El valor del reloj CLOCK_MONOTONIC no puede establecerse a través de clock_settime().

clock_settime() da una pista importante: los sistemas POSIX son capaces de cambiar de forma arbitraria CLOCK_REALITME con él, así que no confíe en él fluye ni continua ni hacia delante. NTP podría implementarse usando clock_settime(), y solo podría afectar CLOCK_REALITME.

El kernel de Linux aplicación parece tomar el tiempo de arranque como la época de CLOCK_MONOTONIC: Starting point for CLOCK_MONOTONIC