2012-03-01 21 views
8

SO: Windows 7WinAPI Sleep() llamada a la función duerme durante más tiempo de lo esperado

Cuando se llama a la función API de Windows Sleep() como del sueño (1) el hilo en realidad tiene capacidad para 15 ms. Lo hice 100 veces en un bucle y el tiempo de suspensión total fue de 1500ms en vez de 100.

¿Es este comportamiento común o debería ser informado sobre algo que está mal con mi instalación de MOBO, CPU, Windows?

EDITAR: Si es posible, podría ejecutar este código y publicar cuánto tiempo durmió. Dejé que un amigo mío manejara esto, y él realmente lo tenía todo en 1ms.

#include <iostream> 
#include <ctime> 
#include <Windows.h> 

void test(void) 
{ 
    std::cout << "Testing 1ms sleep." << std::endl; 

    for (unsigned int i = 0; i < 10; i++) 
    { 
     std::clock_t startClocks = std::clock(); 

     Sleep(1); 

     std::clock_t clocksTaken = std::clock() - startClocks; 
     std::cout << "Time: " << clocksTaken << "ms." << std::endl; 
    } 
} 

int main(void) 
{ 
    test(); 

    std::cin.sync(); 
    std::cin.get(); 
    return 0; 
} 

Edit2: Parece que la razón por qué algunas personas son cada 1ms es que algún otro programa en ejecución que establece la resolución del temporizador de todo el sistema a 1 ms. Por defecto debería ser 15.6ms en Windows 7.

+0

Desde sueño puede fácilmente tomar un tiempo diferente en función de diversos factores (el hardware/O se está ejecutando, la carga del procesador en ese momento, etc.) No estoy seguro de lo que espera lograr pidiéndole a las personas que ejecuten ese código. Sería perfectamente posible que produzca un tiempo diferente para cada iteración del ciclo, cada vez que se ejecuta. – obmarg

+0

No creo que Sleep() sea hardware específico en Windows. Si no está ejecutando ningún programa que use timeBeginPeriod(), entonces los resultados deberían ser de 15-16ms. Por ejemplo: Windows Media Player lo configura en 10 ms y BSPlayer en 1 ms. También se ha dicho que algunos navegadores lo ajustan. – NFRCR

+0

Quizás no esté conectado directamente, pero aún podría haber un enlace indirecto: si está ejecutando Windows en una máquina muy poco potente, la carga aumentaría y el tiempo antes de que Sleep también pudiera volver. – obmarg

Respuesta

7

¿Este comportamiento común

Es.

El programador de hilos de la ventana funciona en un cuanto de tiempo (la longitud exacta depende de varios factores, incluida la versión y edición de Windows). Efectivamente, cualquier retardo distinto de cero se redondea a un cuanto completo.

+0

@MatteoItalia Un sueño cero regresará inmediatamente si no hay nada más disponible para ejecutar (con esta o mayor prioridad): es posible que no se bloquee en absoluto. Con un valor distinto de cero, según tengo entendido, siempre habrá algún bloqueo. – Richard

+0

correcto, eliminando. –

0

(depuración o liberar construir?)

¿Cómo mide el retraso? ¿Estás usando un método preciso? (queryperformancecounter)

No creo que deba confiar en el sistema operativo Windows para obtener una sincronización precisa; no es un sistema operativo en tiempo real, y habrá "fuerzas" externas que robarán tiempo de su proceso.

11

Dormir puede hacer que el hilo duerma más tiempo que el tiempo de espera especificado, solo garantiza que el hilo durmirá durante al menos ese período de tiempo.

Desde el documentation:

Después del intervalo de reposo ha pasado, el hilo está listo para funcionar. Si especifica 0 milisegundos, el subproceso abandonará el resto de su intervalo de tiempo, pero permanecerá listo. Tenga en cuenta que no está garantizado que un hilo listo se ejecute inmediatamente. En consecuencia, es posible que el subproceso no se ejecute hasta un tiempo después de que transcurra el intervalo de inactividad. Para obtener más información, consulte Scheduling Priorities.

1

Este es un comportamiento bastante normal, como la mayoría de las resoluciones de reloj son alrededor de 10-15 ms. Por lo tanto, si lo llama con un valor inferior a la resolución del reloj (en su caso, 1), es probable que tenga que esperar al menos un ciclo de reloj, por lo que duerme más tiempo de lo que desea.

En general, no debe utilizar Suspensión para las cosas que requieren tal precisión debido a estos problemas.

2

Los mejores artículos que he encontrado con respecto al tiempo en Windows son here y here. La parte útil es que una vez que cambia la resolución del temporizador multimedia (por ejemplo, timeBeginPeriod(1) por 1 ms), también afecta al comando Suspender, porque afecta al programador en general. Dicho esto, lograr una precisión de 1 ms no es factible en un SO no en tiempo real.

1

El comportamiento es correcto. El hardware subyacente, la versión de SO e incluso el software en ejecución están influyendo en el hábito del SO con respecto a la función sleep().

Si se invoca un reposo con dwMilliseconds menor que el período de interrupción del sistema, la llamada volverá en la siguiente interrupción. De esta forma, la demora real depende del momento en que se llamó a la suspensión (con respecto al período de interrupción).

Se recomienda utilizar la interfaz del temporizador multimedia para aumentar la frecuencia de interrupción al máximo admitido por el hardware, cuando se desea una suspensión (1).

Una descripción detallada acerca de la función del sueño(), funciones de reloj temporizador de espera, las resoluciones del temporizador, ya programar el temporizador multimedia se puede encontrar en la Windows Timestamp Project

Cuestiones relacionadas