Dormir por milisegundos


632

Sé que la sleep(x)función POSIX hace que el programa duerma durante x segundos. ¿Existe una función para hacer que el programa duerma x milisegundos en C ++?


77
Debe tener en cuenta que, en Windows de todos modos, Sleep()tiene una precisión de milisegundos , pero su precisión puede ser mucho mayor. Puede pensar que duerme durante 4 milisegundos, pero en realidad duerme durante 400.
John Dibling

55
@ John Dibling: Creo que está usando POSIX sleep, no win32 Sleepdado "x segundos".
CB Bailey

1
Aunque C y C ++ tienen nombres diferentes, que pueden ser una fuente de errores e incompatibilidades, en la mayoría de los casos está bien usar encabezados C en C ++. Sin embargo, si desea estar absolutamente seguro de que nada sale mal, #includeel encabezado C dentro de un extern "C" {}bloque. Además, si tiene archivos fuente C y C ++ en el mismo proyecto, se recomienda encarecidamente que haga esto para evitar cualquier problema, especialmente si incluye los mismos encabezados en ambos tipos de archivos fuente (en cuyo caso esto es necesario) . Si tiene un proyecto puramente C ++, podría funcionar sin ningún problema.
adam10603

2
@ JohnDibling no, no 400ms. La peor precisión que podría haber obtenido fue de Windows 9x, que GetTickCounttenía una resolución de 55 ms; Las versiones posteriores tenían una resolución de 16 ms o menos. Un usuario pensó que estaba obteniendo una resolución de 16 ms de Sleep, pero luego informó que Sleepera bastante preciso y que la aparente imprecisión fue causada por el uso GetTickCountpara medir el paso del tiempo.
Qwertie

Respuestas:


457

Tenga en cuenta que no hay una API C estándar para milisegundos, por lo que (en Unix) tendrá que conformarse usleep, lo que acepta microsegundos:

#include <unistd.h>

unsigned int microseconds;
...
usleep(microseconds);

2
¿Es un sueño ocupado? Necesito ceder a otro hilo durante el sueño; puedo usar usleeppara eso?
Michael

13
No es una espera ocupada stackoverflow.com/a/8156644/1206499 , y nanosleeppuede ser una mejor opción ya que usleepes obsoleta.
jswetzen

44
Niet, considera mencionar la respuesta de @ HighCommander4, que es más portátil si tienes un compilador de C ++ 11.
einpoklum

66
usleep () desaprobado en POSIX en 2001 y eliminado en 2008.
Jetski S-type

1271

En C ++ 11, puede hacer esto con las instalaciones de biblioteca estándar:

#include <chrono>
#include <thread>
std::this_thread::sleep_for(std::chrono::milliseconds(x));

Claro y legible, ya no es necesario adivinar qué unidades sleep()toma la función.


66
¿Std :: this_thread :: sleep_for define un punto de interrupción? Como boost :: this_thread_sleep hace?
Martin Meeser

73
Esta es la forma correcta de hacerlo. Período. El hilo es multiplataforma y crono.
Nulo

88
@Vacío. Una muy buena manera, sin duda, pero "el" y "período" son palabras terriblemente fuertes.
Físico loco

55
¿Es un sueño ocupado? Necesito ceder a otro hilo durante el sueño; puedo usar sleep_forpara eso?
Michael

14
@ Michael: No es un sueño ocupado, cederá el paso a otros hilos.
HighCommander4

83

Para mantenerse portátil, puede usar Boost :: Thread para dormir:

#include <boost/thread/thread.hpp>

int main()
{
    //waits 2 seconds
    boost::this_thread::sleep( boost::posix_time::seconds(1) );
    boost::this_thread::sleep( boost::posix_time::milliseconds(1000) );

    return 0;
}

Esta respuesta es un duplicado y se ha publicado en esta pregunta anteriormente. Quizás puedas encontrar algunas respuestas útiles allí también.


66
Tenga en cuenta que, en un entorno multiproceso, boost::this_thread::sleepagrega un punto de interrupción a su código. boost.org/doc/libs/1_49_0/doc/html/thread/…
Martin Meeser

35

En Unix puedes usar usleep .

En Windows hay suspensión .


44
y la llamada de Windows está en milisegundos.
shindigo

17
Debe incluir <unistd.h> o <Windows.h> respectivamente.
gbmhunter

Sí, pero ¿no podría la resolución de tiempo real ser 15-16 ms (incluso si la unidad en la llamada es 1 ms) y, por lo tanto, el tiempo mínimo sería 15-16 ms?
Peter Mortensen

33

Dependiendo de su plataforma que pueda tener usleepo nanosleepdisponible. usleepestá en desuso y se ha eliminado del estándar POSIX más reciente; nanosleepse prefiere.


66
Tenga en cuenta que mientras usleep()se declara en <unistd.h>, confusamente, nanosleep()se declara en <time.h>/ <ctime>.
gbmhunter

27

¿Por qué no usar la biblioteca time.h? Se ejecuta en sistemas Windows y POSIX:

#include <iostream>
#include <time.h>

using namespace std;

void sleepcp(int milliseconds);

void sleepcp(int milliseconds) // Cross-platform sleep function
{
    clock_t time_end;
    time_end = clock() + milliseconds * CLOCKS_PER_SEC/1000;
    while (clock() < time_end)
    {
    }
}
int main()
{
    cout << "Hi! At the count to 3, I'll die! :)" << endl;
    sleepcp(3000);
    cout << "urrrrggghhhh!" << endl;
}

Código corregido: ahora la CPU permanece en estado inactivo [2014.05.24]:

#include <iostream>
#ifdef _WIN32
    #include <windows.h>
#else
    #include <unistd.h>
#endif // _WIN32

using namespace std;

void sleepcp(int milliseconds);

void sleepcp(int milliseconds) // Cross-platform sleep function
{
    #ifdef _WIN32
        Sleep(milliseconds);
    #else
        usleep(milliseconds * 1000);
    #endif // _WIN32
}
int main()
{
    cout << "Hi! At the count to 3, I'll die! :)" << endl;
    sleepcp(3000);
    cout << "urrrrggghhhh!" << endl;
}

24
Uno de los problemas con ese código es que es un bucle ocupado, continuará usando el 100% de un núcleo de procesador único. La función de suspensión se implementa alrededor de una llamada del sistema operativo que detendrá el hilo actual y hará otra cosa, y solo despertará el hilo cuando expire el tiempo especificado.
Ismael

Tienes razón: consumirá el 100% de un núcleo de una CPU. Así que aquí está el código reescrito usando las funciones de suspensión del sistema, y ​​todavía es multiplataforma:
Bart Grzybicki

@BartGrzybicki Sé que esta es una respuesta antigua y todo, pero en Visual Studio 2017 en una máquina con Windows, #ifdef WIN32no se evalúa como verdadero por defecto.
kayleeFrye_onDeck

2
El código de @kayleeFrye_onDeck está mal. Debería ser #ifdef _WIN32.
Contango

1
@Contango ¡Lo sabía! Pero no cuando escribí eso ... jajaja. ¡Gracias por el seguimiento!
kayleeFrye_onDeck

17

nanosleepes una mejor opción que usleep: es más resistente a las interrupciones.


66
Estaba familiarizado con usleep, pero no nanosleep. Debe proporcionar un ejemplo de uso en Linux.
jww


7

Si usa MS Visual C ++ 10.0, puede hacerlo con las instalaciones de biblioteca estándar:

Concurrency::wait(milliseconds);

necesitará:

#include <concrt.h>

10
No use la palabra "estándar" cuando no lo diga en serio. no<concrt.h> es un encabezado de biblioteca estándar; puede ser una biblioteca de plataforma; en cuyo caso debe indicar claramente los requisitos previos.
Toby Speight

5

En plataformas con la selectfunción (POSIX, Linux y Windows) puede hacer:

void sleep(unsigned long msec) {
    timeval delay = {msec / 1000, msec % 1000 * 1000};
    int rc = ::select(0, NULL, NULL, NULL, &delay);
    if(-1 == rc) {
        // Handle signals by continuing to sleep or return immediately.
    }
}

Sin embargo, hay mejores alternativas disponibles hoy en día.


Parece que no se puede compilar en VS2017 en una máquina con Windows:error LNK2019: unresolved external symbol _select@20 referenced in function "void __cdecl sleep(unsigned long)" (?sleep@@YAXK@Z)
kayleeFrye_onDeck

@kayleeFrye_onDeck Se compila. Simplemente no se vincula. Busque sus documentos de Windows.
Maxim Egorushkin

¿Qué encabezado utilizas para timeval?
Totte Karlsson

@TotteKarlsson <sys/time.h>.
Maxim Egorushkin

4

La forma de dormir su programa en C ++ es el Sleep(int)método. El archivo de encabezado es#include "windows.h."

Por ejemplo:

#include "stdafx.h"
#include "windows.h"
#include "iostream"
using namespace std;

int main()
{
    int x = 6000;
    Sleep(x);
    cout << "6 seconds have passed" << endl;
    return 0;
}

El tiempo que duerme se mide en milisegundos y no tiene límite.

Second = 1000 milliseconds
Minute = 60000 milliseconds
Hour = 3600000 milliseconds

3
¿Qué quieres decir con que no tiene límite? Seguramente tiene un límite que es 0xFFFFFFFE. Esperar a 0xFFFFFFFF simplemente no expirará (lo que significa que esperará hasta que finalice el programa).
Izzy

No quise decir eso, Izzy, perdón por nuestro malentendido. Quise decir que puedes ingresar cualquier número positivo de milisegundos. Por lo tanto, esperará tantos milisegundos para cerrar el programa. Si no entiende, por favor dígalo, le explicaré más.
Phi

Sí, pero ¿cuál es la resolución de tiempo real? ¿No podrían ser 15-16 ms en algunos casos? Por ejemplo, si usa Sleep (3), ¿realmente dormirá durante 3 ms o en lugar de 15-16 ms?
Peter Mortensen

3

Seleccionar llamada es una forma de tener más precisión (el tiempo de suspensión se puede especificar en nanosegundos).


Si bien esto podría ser una pista valiosa para resolver el problema, una buena respuesta también demuestra la solución. Por favor edición para proporcionar código de ejemplo para mostrar lo que quiere decir. Alternativamente, considere escribir esto como un comentario.
Toby Speight

3

Utilice los subprocesos asíncronos de entrada / salida de Boost, duerma durante x milisegundos;

#include <boost/thread.hpp>
#include <boost/asio.hpp>

boost::thread::sleep(boost::get_system_time() + boost::posix_time::millisec(1000));

¿Qué pasará realmente si intentas dormir durante 3 milisegundos? ¿Serán 15-16 milisegundos en su lugar? ¿Lo has medido?
Peter Mortensen

1

La pregunta es antigua, pero logré encontrar una manera simple de tener esto en mi aplicación. Puede crear una macro C / C ++ como se muestra a continuación, úsela:

#ifndef MACROS_H
#define MACROS_H

#include <unistd.h>

#define msleep(X) usleep(X * 1000)

#endif // MACROS_H

1

Desde C ++ 14 usando std y también sus literales numéricos:

#include <chrono>
#include <thread>

using namespace std::chrono;

std::this_thread::sleep_for(123ms);

0

Como reemplazo de Win32 para sistemas POSIX:

void Sleep(unsigned int milliseconds) {
    usleep(milliseconds * 1000);
}

while (1) {
    printf(".");
    Sleep((unsigned int)(1000.0f/20.0f)); // 20 fps
}

Prefiero nanosleep()a usleep(): éste es obsoleto y ha sido borrado de la norma más reciente POSIX.
Toby Speight
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.