c ++, usleep () es obsoleto, soluciones para Windows / MingW?

Ya me enteré con otra pregunta que Windows / MingW no proporciona las alternativas nanosleep () y setitimer () al usleep obsoleto (). Pero mi objective es arreglar todas las advertencias que me da cppcheck, incluidas las advertencias de estilo usleep ().

Entonces, ¿hay alguna solución para evitar usleep () en Windows sin usar cygwin o instalar cargas de nuevas dependencias / bibliotecas? Gracias.

usleep() funciona con microsegundos. En las ventanas para obtener una precesión de microsegundos, debe usar la función QueryPerformanceCounter () winapi. Aquí puede encontrar cómo obtener esa precesión al usarla.

Utilicé este código de (originalmente desde aquí ):

 #include  void usleep(__int64 usec) { HANDLE timer; LARGE_INTEGER ft; ft.QuadPart = -(10*usec); // Convert to 100 nanosecond interval, negative value indicates relative time timer = CreateWaitableTimer(NULL, TRUE, NULL); SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0); WaitForSingleObject(timer, INFINITE); CloseHandle(timer); } 

Tenga en cuenta que SetWaitableTimer() utiliza ” intervalos de 100 nanosegundos … Los valores positivos indican tiempo absoluto. … Los valores negativos indican el tiempo relativo. ” Y que ” La precisión real del temporizador depende de la capacidad de su hardware.

Si tiene un comstackdor de C ++ 11, puede usar esta versión portátil:

 #include  #include  ... std::this_thread::sleep_for(std::chrono::microseconds(usec)); 

Felicitaciones a Howard Hinnant que diseñó la increíble biblioteca (y cuya respuesta a continuación merece más amor).

Si no tiene C ++ 11, pero tiene impulso, puede hacer esto en su lugar:

 #include  #include  ... boost::this_thread::sleep(boost::posix_time::microseconds(usec)); 

El régimen de milisegundos de la función Sleep() está bien descrito y bien entendido. No hace nada impredecible. A veces se culpa a la función de realizar impredecibles, es decir, regresar antes de que el retraso haya expirado. Necesito decir que esto está mal. Una investigación cuidadosa confirmará que su comportamiento es absolutamente predecible. El único problema es que hay mucho que leer y la mayor parte es infantil. También se dice a menudo que windows no es un sistema operativo en tiempo real. Pero tales comentarios no aportan nada, además esos comentarios se utilizan para ocultar la falta de conocimiento. Me pone un poco enojado, ni siquiera Microsoft lo nota y proporciona una mejor documentación.

Sin embargo, sin exagerar esta pequeña respuesta: La función sleep () es precisa, cuando se usa de forma adecuada y cuando se conocen sus características. Se debe prestar especial atención al sueño (0). Esta es una herramienta muy poderosa, particularmente cuando se usa junto con la clase de prioridad del proceso, la prioridad del subproceso, la configuración del temporizador multimedia y la máscara de afinidad del procesador.

Por lo tanto, en general, un sueño real se puede realizar de manera fácil y segura hasta el período de interrupción del sistema. Cuando se trata de dormir más corto que el período de interrupción, se requiere un giro. Se debe usar una fuente de tiempo de mayor resolución en oder para girar durante periodos de tiempo más cortos. La fuente más común para esto es el contador de rendimiento. QueryPerformanceCounter(*arg) entrega un incremento * arg. QueryPerformanceFrequency(*arg) proporciona la frecuencia a la que se incrementa el contador de rendimiento. Esto es típicamente en el régimen de MHz y varía, dependiendo del hardware subyacente. Una frecuencia en el rango de MHz proporciona una resolución de microsegundos. De esta forma, se puede usar algo de alta resolución para esperar a que expire un lapso de tiempo deseado. Sin embargo, la precisión de esto debe analizarse detenidamente: el sistema operativo devuelve la frecuencia del contador de rendimiento como una constante. ¡Esto está mal! Como la frecuencia se genera como un dispositivo físico, siempre hay un desplazamiento y tampoco una constante. Tiene deriva térmica. Los sistemas más modernos tienen menos deriva. Pero si la deriva térmica es solo 1ppm, el error será 1us / s. El desplazamiento puede ser fácilmente varios 100. Un desplazamiento de 100 en 1 MHz corresponde a 100us / s.

Si un hilo esperará en cualquier momento a alta resolución, establecerá un hilo de servicio. Ambos hilos compartirán un evento nombrado. El subproceso de servicio dormirá hasta 1 período de interrupción antes del retardo de espera deseado y luego activará el contador de rendimiento para el microsegundo restante. Cuando el hilo de servicio llega al tiempo final, establece el evento nombrado y finaliza. El hilo que llama se activará, ya que estaba esperando el evento nombrado por medio de una función de espera.

Resumen:

  • El sueño se entiende bien pero está mal documentado.
  • Un hilo de servicio puede imitar sueños en alta resolución.
  • Dicho hilo de servicio podría establecerse como un servicio de todo el sistema.
  • La precisión del contador de rendimiento debe observarse cuidadosamente. Se requiere una calibración.

Se puede encontrar información más detallada en el Windows Timestamp Project

Nueva respuesta para una vieja pregunta:

Justificación de la nueva respuesta: las herramientas / sistemas operativos se han actualizado de modo que haya una mejor opción ahora que cuando se formuló originalmente la pregunta.

Los encabezados C ++ 11 y std han estado en el conjunto de herramientas de VS desde hace varios años. Usando estos encabezados esto se codifica mejor en C ++ 11 como:

 std::this_thread::sleep_for(std::chrono::microseconds(123)); 

Estoy usando microsegundos solo como un ejemplo de duración. Puede usar cualquier duración que le resulte conveniente:

 std::this_thread::sleep_for(std::chrono::minutes(2)); 

Con C ++ 14 y algunas directivas de uso, esto se puede escribir un poco más compacto:

 using namespace std::literals; std::this_thread::sleep_for(2min); 

o:

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

Esto definitivamente funciona en VS-2013 (modulo chrono-literales). No estoy seguro de las versiones anteriores de VS.

Depende de la granularidad que necesites. Si está hablando en milisegundos, la función Sleep de Win32 hará el trabajo; consulte http://msdn.microsoft.com/en-us/library/ms686298%28v=vs.85%29.aspx . Si habla microsegundos, entonces no hay una manera fácil de hacerlo, y sería afortunado obtener ese tipo de resolución de temporizador en Windows (que no es un RTOS), o en Linux, vaya a eso.

Encontré esta publicación en el blog sobre eso . Utiliza QueryPerformanceCounter . La función publicada:

 #include  void uSleep(int waitTime) { __int64 time1 = 0, time2 = 0, freq = 0; QueryPerformanceCounter((LARGE_INTEGER *) &time1); QueryPerformanceFrequency((LARGE_INTEGER *)&freq); do { QueryPerformanceCounter((LARGE_INTEGER *) &time2); } while((time2-time1) < waitTime); } 

Espero que esto ayude un poco.