HOWTO · C++

Agregar retardo cronometrado en C++

Este tutorial le brindará una breve guía sobre cómo agregar un retraso cronometrado en su programa C++.

En esta página

Un programa de C++ puede pausar su hilo actual mediante una API de la plataforma o las funciones de espera de hilos de la biblioteca estándar. Elija según la portabilidad y según si el plazo se expresa como una duración o como una hora del reloj: sleep() usa segundos enteros en sistemas POSIX, usleep() usa microsegundos en sistemas POSIX, y sleep_for() y sleep_until() de C++11 aceptan duraciones y puntos temporales. Estas llamadas suspenden el hilo que las invoca; no garantizan que se reanude en un instante exacto.

Elija una API de retraso en C++

Use sleep_for() para una espera relativa portable de C++11 en el código habitual de una aplicación. Use sleep_until() cuando el trabajo deba esperar hasta un plazo definido por un reloj. Las funciones POSIX sleep() y usleep() son útiles cuando el código ya depende de POSIX; no forman parte de las funciones portables de C++. Windows ofrece su propia API Sleep(), cuyo argumento se expresa en milisegundos.

Un retraso bloquea el hilo que lo invoca. Si una interfaz de usuario, un servidor o un grupo de trabajadores debe seguir respondiendo, pause un hilo dedicado o use el temporizador asíncrono del framework en vez de bloquear el hilo principal o el del bucle de eventos.

Use sleep() para retrasos de segundos enteros específicos de la plataforma

C++ no define una función sleep() portable. En sistemas POSIX, declárela con <unistd.h> y llame a sleep(seconds). Si una señal interrumpe la espera, devuelve el número de segundos enteros que todavía se habían solicitado; devuelve cero cuando transcurre el intervalo solicitado. En Windows, incluya <Windows.h> y llame a Sleep(milliseconds): su unidad son los milisegundos, así que un retraso de un segundo se expresa como Sleep(1000). Las llamadas de POSIX y Windows tienen nombres, encabezados y unidades distintos. También puede consultar la guía de Windows.h.

Por ejemplo, en POSIX, incluya <unistd.h> y use sleep(2);. En Windows, incluya <Windows.h> y use Sleep(2000);. Elija la rama correspondiente a la plataforma de destino: declarar la función POSIX no hace que sleep() esté disponible en Windows.

Use usleep() para retrasos de microsegundos en POSIX

En sistemas POSIX, <unistd.h> declara usleep(), que acepta una duración en microsegundos. Por ejemplo, usleep(250000); solicita una pausa de un cuarto de segundo. Es una interfaz POSIX, no una función portable de C++; algunas plataformas o configuraciones de características pueden no ofrecerla. Para código C++ multiplataforma, use sleep_for(). La función devuelve 0 cuando termina la espera y -1 si se interrumpe o falla por otro motivo; compruebe el valor devuelto si el programa debe reaccionar ante una interrupción. El tiempo transcurrido real puede superar el intervalo solicitado porque el sistema operativo planifica los hilos según su propia temporización.

Use sleep_for() para un retraso relativo

Incluya <thread> y <chrono> para esperar una duración relativa. sleep_for() suspende el hilo actual durante al menos la duración solicitada, sujeto a la planificación y a la contención de recursos. Este programa completo de C++11 pausa durante 200 milisegundos y después muestra una confirmación. Ejecute este ejemplo:

El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.

#include <chrono>
#include <iostream>
#include <thread>

int main() {
    std::this_thread::sleep_for(std::chrono::milliseconds(200));
    std::cout << "Wait complete\n";
}
Wait complete

Use un tipo de duración que deje clara la unidad deseada, como std::chrono::seconds(2) o std::chrono::milliseconds(250). La espera afecta únicamente al hilo que la invoca, y los retrasos del planificador pueden hacer que el tiempo transcurrido supere la duración pasada a la función.

Use sleep_until() para esperar hasta un punto temporal

sleep_until() también se encuentra en <thread>, pero acepta un punto temporal de un reloj en vez de una duración. Sume una duración al valor now() de un reloj para formar un plazo futuro; por ejemplo, std::this_thread::sleep_until(std::chrono::steady_clock::now() + std::chrono::seconds(3));. Esto espera hasta ese punto de steady_clock, diseñado para medir intervalos y que no se ajusta como la hora del reloj civil. Si el plazo ya quedó atrás, no se añade ninguna espera. La función no devuelve ningún valor, y la planificación puede hacer que el hilo se reanude después del plazo.

Prefiera steady_clock para los plazos basados en tiempo transcurrido, de modo que un ajuste del reloj del sistema no desplace el objetivo. Use system_clock solo cuando el objetivo sea una hora del reloj civil y tenga en cuenta los cambios que pueda sufrir ese reloj durante la espera. Al igual que sleep_for(), esta función bloquea el hilo que la invoca.

Elija el retraso adecuado y tenga en cuenta la planificación

En código portable de C++11, use sleep_for() cuando el requisito sea «esperar este tiempo» y sleep_until() cuando sea «esperar hasta este plazo». Use sleep() o usleep() solo cuando resulte apropiado depender de POSIX, y use Sleep() de Windows en código específico para Windows. Mantenga visibles las unidades: sleep() recibe segundos, usleep() recibe microsegundos, Sleep() de Windows recibe milisegundos y <chrono> representa las duraciones mediante tipos con nombre.

Ninguna de estas API es un temporizador de precisión. El tiempo solicitado es un objetivo mínimo de espera, no una promesa sobre el instante exacto de reanudación; la planificación, la contención y las interrupciones influyen en cuándo continúa la ejecución. Para esperas breves que no deban bloquear un hilo, use un temporizador asíncrono de la plataforma o del framework. Esta distinción ayuda a elegir un retraso que se ajuste tanto a las necesidades de portabilidad del programa como a su modelo temporal.