pause library c++ boost sleep

library - Son los sueños más largos(en C++) menos precisos que los cortos



usleep c++ (8)

Cuando duermes (N), le indica al sistema operativo que active el subproceso en el momento actual + N.

La razón por la que no siempre es precisa, es que no eres el único hilo en el sistema.
Es posible que haya otro subproceso que haya sido despertado en ese momento antes que usted, y podría haber algunas cosas importantes del sistema operativo que deben realizarse exactamente en ese momento.

De todos modos, no debería haber problemas de precisión, porque el método no tiene nada que ver con N.

La única razón por la que no será "preciso" es si se trata de un sistema operativo horrible que no puede calcular el tiempo correcto. Y luego otra vez, el bucle no resolverá eso.

Tengo la tarea de hacer algo cada minuto "redondo" (en xx: xx: 00) Y uso algo como

const int statisticsInterval=60; time_t t=0; while (1) { if (abs(t-time(NULL)==0)) //to avoid multiple calls in the same second that is the multiple of 60 boost::this_thread::sleep(boost::posix_time::seconds(2));//2, not 1 to make sure that 1 second passes t=time(NULL); boost::this_thread::sleep(boost::posix_time::seconds(statisticsInterval-(t%statisticsInterval))); //DO WORK }

Como puede ver, uso el modo de suspensión (60 seg. - número de segundos transcurridos en el minuto actual). Pero un programador me dijo que no es preciso y que debería cambiarlo a while loop with sleep (1) en el interior. Considero altamente dudoso que él tenga razón, pero solo quería comprobar si alguien sabe si hay menos precisión si el intervalo de sueño es largo. Supongo que la suspensión se implementa de manera que en cierto momento en el futuro se active el activador y el subproceso se ponga en "listo para ejecutar el grupo de subprocesos", por lo que no veo ninguna razón para la diferencia en la precisión. BTW OS es ubuntu y no me importan los errores de menos de 2-3 segundos. Por ejemplo, si duermo durante 52 segundos, 53.8 dormir es totalmente aceptable. PD: Sé que el sueño define el tiempo mínimo, y que, en teoría, mi hilo podría activarse en el año 2047. Pero estoy preguntando sobre escenarios realistas.


El sueño no es muy preciso en muchos casos. Depende del sistema operativo lo preciso. En Windows 7, la resolución del temporizador es de unos 15,4 ms, creo. Además, generalmente puede decirle al programador cómo manejar el aflojamiento del sueño ...

Aquí hay una buena lectura:

Linux: http://linux.die.net/man/3/nanosleep

Windows: http://msdn.microsoft.com/en-us/library/ms686298(v=vs.85).aspx

PD: si desea una mayor precisión en las esperas largas, descanse un poco y use la diferencia horaria en función del reloj en tiempo real. Es decir, almacene la hora actual cuando comienza a dormir, luego, en cada intervalo, compruebe qué tan lejos está del tiempo de espera establecido.


En algunas API de subprocesamiento, es posible despertarse antes de que se complete el sueño (por ejemplo, debido a una señal que llega durante el sueño). La forma correcta de manejar esto es calcular un tiempo de activación absoluto, luego hacer un bucle, durmiendo durante el tiempo restante. Me imagino que dormir a intervalos de un segundo es un truco para aproximarse a esto, mal.

Sin embargo, no está documentado que la API de subprocesos de refuerzo this_thread::sleep() tenga estas primeras activaciones, por lo que esta técnica no es necesaria (la API de subprocesos de refuerzo hace el bucle por ti).

En términos generales, hay muy pocos casos en los que el uso de intervalos de sueño más pequeños mejora significativamente la latencia de activación; El sistema operativo maneja todas las activaciones más o menos de la misma manera. En el mejor de los casos, puede mantener la memoria caché caliente y evitar las salidas de página, pero esto solo afectaría a la pequeña parte de la memoria directamente involucrada en el ciclo de sueño.

Además, la mayoría de los sistemas operativos se ocupan del tiempo utilizando contadores enteros internamente; esto significa que los intervalos grandes no inducen errores de redondeo (como puede encontrar con valores de punto flotante). Sin embargo, si está utilizando un punto flotante para su propio cálculo, esto puede ser un problema. Si actualmente está utilizando intervalos de punto flotante (por ejemplo, un double de segundos desde 1970), es posible que desee considerar unidades enteras (por ejemplo, un long long de milisegundos desde 1970).


En general, el sueño no es el método correcto para sincronizar nada. Es mejor utilizar un temporizador de precisión con una función de devolución de llamada. En Windows, uno puede usar los temporizadores "Multimedia", que tienen una resolución no mayor a 1 ms en la mayoría de los equipos. ver here Cuando el temporizador expira, el sistema operativo llama a la función de devolución de llamada casi en tiempo real. ver here


La implementación de Boost.Thread de la suspensión para los sistemas POSIX puede utilizar diferentes enfoques para la suspensión:

  1. Tiempo de espera en mutex en caso de que el subproceso se cree con Boost.Thread y tenga una información de subproceso específica.
  2. Use pthread_delay_np , si está disponible, y el hilo no se crea con Boost.Thread.
  3. nanosleep si pthread_delay_np no está disponible.
  4. Cree un mutex local y haga una espera temporizada en él (peor de los casos si no hay nada más disponible).

Los casos número 2, 3 y 4 se implementan en un bucle de 5 veces (a partir de Boost 1.44). Por lo tanto, si el hilo para dormir se interrumpe (es decir, con alguna señal) más de 5 veces, puede haber un problema potencial. Pero eso no es probable que suceda.

En todos los casos, la precisión será mucho mayor que un segundo, por lo que hacer varias suspensiones no será más preciso que hacer una larga. Solo puede estar preocupado por el hecho de que su programa se haya cambiado por completo debido al largo tiempo de sueño. Por ejemplo, si la máquina está tan ocupada, entonces el kernel pone todo el programa en el disco. Para evitar que te cambien, debes girar (o dormir menos y levantarte de vez en cuando). Por lo general, si el rendimiento es muy importante, los programas giran en una CPU y nunca llaman a la suspensión, ya que se debe evitar cualquier llamada de bloqueo. Pero eso es cierto si estamos hablando de nano / micro-segundos.


La respuesta es sí. Sin embargo, no tiene nada que ver con C ++. Tiene todo que ver con el sistema operativo.

Debido al mayor enfoque en el uso de baja potencia en los sistemas portátiles actuales, los sistemas operativos se han vuelto más inteligentes con respecto a los temporizadores.

Tanto Windows como Linux usan el temporizador para evitar despertarse con demasiada frecuencia. Esta holgura se calcula automáticamente utilizando la duración del tiempo de espera. Se puede anular de varias maneras si se requiere un temporizador realmente preciso.

Lo que esto hace por el sistema operativo es permitir que entre en estados de sueño realmente profundos. Si los temporizadores se apagan todo el tiempo, la CPU y la RAM no tienen la oportunidad de apagarse. Pero si los temporizadores se agrupan en un lote, la CPU puede encenderse, ejecutar todas las operaciones del temporizador y luego apagarse nuevamente.

Entonces, si hay 10 programas durmiendo durante 60 segundos pero con una diferencia de medio segundo aproximadamente, el uso más eficiente de la CPU es despertarse una vez, ejecutar los 10 temporizadores y luego volver a dormir en lugar de despertarse 10 veces.


La suspensión funciona en términos de cuanto de tiempo del programador y, a menos que reciba una señal, no hay manera de que pueda despertarse antes de que se haya consumido ese cuanto. Además, el sueño no está diseñado para ser preciso o exacto. Además, el tiempo es más una línea de guía que una regla. Se entiende comúnmente como "al menos eso, pero posiblemente en cualquier momento más".
Por lo tanto, sleep(60) veces el sleep(1) nunca puede ser más preciso que el sleep(60) .

Ya que declara que su sistema operativo es Ubuntu, también podría usar un timerfd [1] . Establezca el tiempo de caducidad en 1 minuto y read() en él. Si obtiene EINTR , simplemente read() nuevo. De lo contrario, sabes que un minuto ha terminado.

Esto es lo más preciso que puede obtener (en mi máquina Ubuntu no particularmente impresionante, timerfd s funciona con precisión en un microsegundo sin problema). Como ventaja, también es elegante ... si alguna vez necesitas hacer otra cosa mientras esperas, como escuchar en una toma, puedes conectar el timerfd a la misma epoll como el descriptor de la toma. También puedes compartirlo entre varios procesos y activarlos simultáneamente. O, o, ... muchas otras cosas.


Si el objetivo es dormir hasta una hora determinada del sistema (xx: xx: 00), considere usar la sobrecarga de boost::this_thread::sleep que toma un tiempo , como en boost::posix_time::ptime , en lugar de una duración .

por ejemplo,

#include <iostream> #include <boost/date_time.hpp> #include <boost/thread.hpp> int main() { using namespace boost::posix_time; ptime time = boost::get_system_time(); std::cout << "time is " << time << ''/n''; time_duration tod = time.time_of_day(); tod = hours(tod.hours()) + minutes(tod.minutes() + 1); time = ptime(time.date(), tod); std::cout << "sleeping to " << time << "/n"; boost::this_thread::sleep(time); std::cout << "now the time is " << boost::get_system_time() << ''/n''; }

en C ++ 0x estas dos sobrecargas recibieron nombres diferentes: std::this_thread::sleep_for() y std::this_thread::sleep_until() ;