Pregunta

Si echas un vistazo a clock_gettime () La función, que está disponible en todos los BSD y en realidad se define como parte del estándar POSIX, ve que hay soporte para al menos tres tipos de relojes (muchos sistemas admiten más que estos relojes, pero en realidad el estándar POSIX solo exige uno para estar presente, todos los demás son opcionales):

  • CLOCK_REALTIME : POSIX exige que esté presente. Este es el reloj de pared.

  • CLOCK_MONOTONIC - No tengo idea de qué es esto (y qué significan los segundos SI), pero entiendo que este reloj nunca saltará hacia atrás, solo puede aumentar el valor monotónicamente.

  • CLOCK_UPTIME : no puedo ver cómo esto es diferente a CLOCK_MONOTONIC (el tiempo de actividad también nunca salta hacia atrás), pero al menos sé que este reloj comienza en cero cuando el núcleo arranca (mientras que no está definido qué valor inicial tendrá CLOCK_MONOTONIC cuando arranque el núcleo)

Vamos a ignorar los otros relojes por un segundo. CLOCK_REALTIME no está garantizado para contar monotónicamente hacia arriba, ¿verdad? Esta es la hora real del sistema. Puedo alterar el tiempo del sistema a voluntad. Puedo configurarlo 3 meses en el pasado o 5 años en el futuro y cada vez que mi sistema sincronice la hora usando un servidor NTP en la red, el tiempo podría saltar hacia adelante o hacia atrás.

Ahora tenemos dos funciones para dormir en un sistema BSD. sleep () y nanosleep () . No estoy seguro, pero esperaría que sleep () se implemente encima de nanosleep, después de todo, puedo emular fácilmente sleep () usando nanosleep () y solo establecer el número de segundos en la estructura timepec, manteniendo nanosegundos cero .

He leído en muchas fuentes que estas funciones realmente funcionan calculando la hora de activación (obtenga la hora actual, agregue la cantidad de suspensión) y el sistema verificará a intervalos regulares si la hora actual es más tarde que el tiempo de activación y, de ser así, volverá a activar el hilo. El hecho de que esto solo se verifique en intervalos es la razón por la cual las páginas del manual dicen que el sueño actual dormirá durante al menos esta cantidad de tiempo (más corto solo si es interrumpido por una señal), pero puede dormir más tiempo (dependiendo de la frecuencia el sistema verifica si ya pasamos el tiempo de activación y dependiendo de cuánto tiempo pase antes de que el programador permita que este hilo se ejecute nuevamente).

Esto es perfectamente sensato para mí ... pero hay una pregunta que siempre me molestó:

Según diversas fuentes, los durmientes (al menos el nano sueño) usan CLOCK_REALTIME como reloj interno. Esto significa que si le digo a nanosleep () que duerma durante 30 segundos, luego cambie el reloj de mi sistema a 1 hora en el futuro, el hilo se despertará casi de inmediato (1 hora en el futuro está muy por delante de la hora de despertar nanosleep ( ) calculado). Esto también está perfectamente bien. Sin embargo, ¿qué sucede si digo que se despierte en 30 segundos y luego el usuario descubra que su reloj del sistema está adelantado una hora y lo retrase una hora? ¿Entonces mi hilo dormirá durante 1 hora y 30 segundos? Como eso sería bastante malo.

¿Fue útil?

Solución

Hasta donde yo sé, las funciones de suspensión generalmente se implementan más como un contador decreciente. Dices "dormir por 10 segundos" que se traduce en "dormir por 1000 tics programados" en el programador, y luego cada vez que el programador verifica los procesos de suspensión, disminuye la cantidad de tiempo restante.

De esta manera, el tiempo de sueño siempre será una cantidad de tiempo real para dormir, en lugar de dormir hasta algún momento en el futuro. La razón de esto es como sospechaba, si elegimos una hora en el futuro, es posible que nunca lleguemos allí (o que lleguemos en un tiempo inesperado). Esto es consistente con lo que le gustaría usar dormir en un programa. No está destinado a hacer cálculos tipo calendario.

También puede hacer una prueba simple, hacer que un programa duerma durante 30 segundos, usar el nix " time " comando para cronometrar cuánto tiempo se ejecuta la función, y después de que comience, cambie el reloj del sistema 5 minutos y vea qué sucede.

Otros consejos

El hilo verificará en un contador interno que se establece en la duración del sueño, no en el punto final del sueño. El contador interno utilizado no tiene nada que ver con la hora actual del sistema y, por lo tanto, no se verá afectado si se produce algún cambio en la hora del sistema.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top