¿Cuál es la mejor manera de salir de un bucle después de un tiempo transcurrido de 30 ms en C ++

StackOverflow https://stackoverflow.com/questions/946167

  •  09-09-2019
  •  | 
  •  

Pregunta

¿Cuál es la mejor manera de salir de un bucle tan cerca como sea posible de 30 ms en C ++. Sondeo impulso: microsec_clock? Sondeo QTIME? Algo más?

Algo así como:

A = now;
for (blah; blah; blah) {
    Blah();
    if (now - A > 30000)
         break;
}

Se debe trabajar en Linux, OS X y Windows.

Los cálculos en el bucle son para la actualización de una simulación. Cada 30 ms, me gustaría actualizar la ventana gráfica.

¿Fue útil?

Solución

El ejemplo de fragmento de código en este enlace o menos hace lo que quiere:

http://www.cplusplus.com/reference/clibrary/ctime/ reloj /

Adaptado de su ejemplo:

void runwait ( int seconds )
{
   clock_t endwait;
   endwait = clock () + seconds * CLOCKS_PER_SEC ;
   while (clock() < endwait)
   {
      /* Do stuff while waiting */
   }
}

Otros consejos

  

Los cálculos en el bucle son para   la actualización de una simulación. Cada 30 ms, que había   gustaría actualizar la ventana gráfica.

¿Ha considerado el uso de hilos? Lo que usted describe parece el ejemplo perfecto de por qué debería utilizar hilos en lugar de temporizadores.

El hilo principal proceso mantiene el cuidado de la interfaz de usuario, y tienen un QTimer ajustado a 30 ms para actualizarlo. Se bloquea un QMutex que tienen acceso a los datos, lleva a cabo la actualización, y libera el mutex.

El segundo hilo (ver QThread ) hace la simulación. Para cada ciclo, se bloquea el QMutex, hace los cálculos y libera el mutex cuando los datos están en un estado estable (adecuado para la actualización de la interfaz de usuario).

Con la tendencia creciente en los procesadores multi-núcleo, usted debe pensar cada vez más en el uso de las discusiones que sobre el uso de temporizadores. Sus aplicaciones se beneficia automáticamente de la mayor potencia (múltiples núcleos) de los nuevos procesadores.

Si bien esto no responde a la pregunta, podría darle otro vistazo a la solución. ¿Qué hay de colocar el código de simulación y la interfaz de usuario en diferentes hilos? Si utiliza Qt, actualización periódica se puede realizar mediante un temporizador o incluso QThread :: msleep ( ) . Se puede adaptar el roscado Mandelbrot ejemplo para satisfacer su necesidad.

Si usted tiene que hacer el trabajo hasta que haya transcurrido un cierto tiempo, a continuación, de docflabby respuesta está en el lugar. Sin embargo, si sólo tiene que esperar, sin hacer nada, hasta que haya transcurrido un tiempo especificado, entonces debería usar usleep()

respuesta corta es: no pueden, en general, pero puede hacerlo si se está ejecutando en el sistema operativo derecha o en el hardware adecuado

.

Puede conseguir cerca de 30 ms en todo el sistema operativo de una llamada usando el montaje en sistemas Intel y algo más en otras arquitecturas. Voy a desenterrar la referencia y editar la respuesta para incluir el código cuando lo encuentro.

El problema es el algoritmo de segmentación de tiempo y de lo cerca del final de su segmento de tiempo, usted está en un sistema operativo multitarea.

En algún tiempo real del sistema operativo, hay una llamada al sistema en una biblioteca del sistema se puede hacer, pero no estoy seguro de lo que sería esa llamada.

editar: LOL! Alguien ya ha publicado un fragmento similar en SO: en nano segundos utilizando C ++

VonC tiene el comentario con el código de montaje del temporizador de la CPU en el mismo.

De acuerdo a su pregunta, cada 30 ms que le gustaría actualizar la ventana gráfica. Escribí una aplicación similar, una vez que el hardware sondeado cada 500 ms para cosas similares. Si bien esto no responde directamente a su pregunta, tengo los siguientes seguimientos:

  • ¿Está seguro que Bla (), para la actualización de la ventana gráfica, se puede ejecutar en menos de 30 ms en cada caso?
  • parece más como correr Bla () que se haría mejor mediante una devolución de llamada del temporizador.
  • Es muy difícil encontrar un objeto de temporizador biblioteca que empujará en un intervalo de 30 ms que hacer cambios en un marco gráfico. En Windows XP me encontré con que el temporizador estándar API de Win32 que empuja a los mensajes de ventana al expirar el temporizador de intervalos, incluso en un 2 GHz P4, no podía hacer actualizaciones más rápido que un intervalo de 300 ms, no importa qué tan bajo puedo configurar el intervalo de tiempo en el que Temporizador. Si bien hubo temporizadores de alto rendimiento disponibles en la API Win32, tienen muchas restricciones, es decir, que no se puede hacer ningún IPC (como widgets de actualización de la interfaz de usuario) en un circuito como el que se ha citado anteriormente.
  • Básicamente, el resultado es que hay que planificar cuidadosamente la forma en que desea tener ocurren cambios. Es posible que necesite usar hilos, y ver cómo se desea actualizar la ventana gráfica.

Sólo algunas cosas en que pensar. Me cogieron por sorpresa cuando trabajé en mi proyecto. Si usted ha pensado en estas cosas a través de ya, ignore mi respuesta:. 0)

Se puede considerar simplemente actualizando el visor cada N pasos de simulación en lugar de cada milisegundos K. Si esto es (por ejemplo) una seria aplicación comercial, entonces usted está probablemente va a querer ir a la ruta multi-hilo sugerido en otro lugar, pero si (por ejemplo) es para uso personal o público limitado y lo que está realmente interesado en son los detalles de lo que sea que están simulando, y luego cada-N-pasos es simple, portátil y bien puede ser lo suficientemente bueno para ser seguir adelante con.

Ver QueryPerformanceCounter y QueryPerformanceFrequency

Si está utilizando Qt, aquí es una manera simple de hacer esto:

QTimer* t = new QTimer( parent ) ;
t->setInterval( 30 ) ; // in msec
t->setSingleShot( false ) ;
connect( t, SIGNAL( timeout() ), viewPort, SLOT( redraw() ) ) ;

Usted necesita especificar viewPort y redraw(). A continuación, iniciar el temporizador con t->start().

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top