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 ++?

Prasanth Madhavan
fuente
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);
Niet the Dark Absol
fuente
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.

HighCommander4
fuente
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.

MOnsDaR
fuente
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 .

EN S
fuente
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.

CB Bailey
fuente
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;
}
Bart Grzybicki
fuente
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.

Johan Kotlinski
fuente
66
Estaba familiarizado con usleep, pero no nanosleep. Debe proporcionar un ejemplo de uso en Linux.
jww
14
#include <windows.h>

Sintaxis:

Sleep (  __in DWORD dwMilliseconds   );

Uso:

Sleep (1000); //Sleeps for 1000 ms or 1 sec
foobar
fuente
3
¿Qué necesitas incluir para esto?
ʇolɐǝz ǝɥʇ qoq
#include <WinBase.h>
foobar
77
No, usted necesita#include <windows.h>
ʇolɐǝz ǝɥʇ qoq
77
La pregunta implica fuertemente que se requiere una solución POSIX.
Toby Speight
7

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

Concurrency::wait(milliseconds);

necesitará:

#include <concrt.h>
Metronit
fuente
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.

Maxim Egorushkin
fuente
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
Fi
fuente
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).

Madhava Gaikwad
fuente
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));
Anum Sheraz
fuente
¿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
VPZ
fuente
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);
Martin Flaska
fuente
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
}
lama12345
fuente
Prefiero nanosleep()a usleep(): éste es obsoleto y ha sido borrado de la norma más reciente POSIX.
Toby Speight