2009-06-06 23 views
6

Hay varios hilos en mi aplicación que funcionan en segundo plano. Se conectan a la base de datos y ejecutan algunas consultas de selección que consumen mucho tiempo. En la mayoría de los casos, estas consultas devuelven solo varios registros. De vez en cuando, sin embargo, pueden devolver decenas de miles de registros. Todos estos son procesados ​​en un bucle.Delphi: tiempo de suspensión del hilo de ajuste

Dado que tal situación puede ocurrir en varios subprocesos al mismo tiempo, no quiero que mi aplicación use el 100% del tiempo de CPU cuando esos subprocesos procesan datos; tampoco quiero hacer que todos los hilos pelee por el tiempo del procesador. Por lo tanto, invoco la función Sleep() en cada iteración de los bucles en esos hilos.

No sé, sin embargo, cómo ajustar el tiempo de suspensión. No quiero que los bucles duren para siempre, por lo que el período de sueño no puede ser demasiado largo. Lo ajusto a 2 milisegundos en cada iteración (en cada hilo) (¿por qué 2ms? - esa es una buena pregunta :)).

Pensé, por otro lado, que podría prolongar el tiempo de sueño, pero llamar a dormir solo una vez cada iteraciones (digamos, dormir (100) cada 50 iteraciones). ¿Qué enfoque debo elegir? Una acción de los bucles toma aproximadamente 30 ms cada uno (sin ningún sueño).

Por favor, asesorar.

Gracias!
Mariusz.

Respuesta

9

Llamar a Dormir() no tiene sentido. Use toda la potencia de procesamiento que pueda obtener y deje que el sistema encuentre la mejor manera de programar sus hilos. Llamar al Sleep() solo causará interruptores de contexto adicionales y reducirá el rendimiento. Si el procesamiento de fondo interfiere con su hilo principal u otras aplicaciones, entonces disminuya la prioridad de los hilos de fondo en consecuencia.

Si desea dejar que los subprocesos duerman para limitar la cantidad de datos que generan para los consumidores, consulte las colas productor-consumidor. Haga que los hilos del productor simplemente se bloqueen cuando su cola está llena, de esta manera no necesitará enredarse con el tiempo.

Tenga en cuenta también que el uso de la CPU máxima generalmente es algo bueno, especialmente en los procesadores modernos. Incluso en las computadoras portátiles que tienen un tiempo corto de carga alta es mejor que prolongar artificialmente el tiempo que su tarea necesita, ya que el procesador/sistema completo podrá ingresar antes a los estados de energía más bajos.

+0

Pero no si este se ejecuta en segundo plano en un equipo que también tiene a alguien trabajando en (por ejemplo, escribir una hoja de cálculo), lo hace quiere que el proceso en segundo plano haga inutilizable el proceso en primer plano. – dummzeuch

+2

Cierto, pero es por eso que escribí que la prioridad del hilo de fondo puede reducirse, manteniendo el resto de las aplicaciones (o el hilo principal) receptivo y al mismo tiempo usando todo el potencial del sistema. En los sistemas modernos (multi-núcleo) mantener todos los núcleos suficientemente cargados es un problema mucho más que la falta de capacidad de respuesta de la aplicación en primer plano. Y la E/S masiva no optimizada es una amenaza mucho mayor para la usabilidad de un sistema que la alta carga de la CPU, de todos modos. – mghie

2

Puede haber mejores enfoques que usar sleep para controlar sus hilos. Dado que su llamada a la base de datos puede devolver 1-1000s de registros para su procesamiento, podría tener sentido separar la aplicación en dos capas, tal vez utilizando una cola de mensajes para almacenar las solicitudes. Su aplicación podría llamar a un servicio de datos y el servicio de datos ejecutaría la consulta y enviaría mensajes de datos individuales (o bloques de mensajes, etc.) a una cola. Su aplicación puede crear tantos hilos como sea apropiado para procesar mensajes. Más hilos significa un procesamiento más rápido a expensas de la CPU, pero puede ajustar esto para obtener el equilibrio correcto.

3

Es mejor hacer subprocesos de baja prioridad y dejarlos trabajar sin dormir, de lo contrario no se utiliza toda la potencia de la CPU. Por ejemplo, en sistemas multi-core/multi-cpu. O si su sistema está 100% inactivo: ¿por qué esperar o dormir?

Pero si necesita dormir algunas veces, tenga en cuenta que sleep (1) espera 10-15ms (!) Debido al timescle predeterminado de Windows. Puede usar timeBeginPeriod (1) de la unidad MMSystem.pas para establecer la resolución en 1 ms :-) (Lo usé para comunicación serial).

0

use TThread.Sleep() de System.Classes, en lugar de Sleep() de WinApi.Ventanas

// Winapi.Windows contains GetTickCount and Sleep 
// System.Classes contains TThread (universal option) // TThread.GetTickCount() // TThread.Sleep() 
uses System.Types, System.Classes, Vcl.Forms; 

// entonces en su proceso utilice el siguiente

TThread.Sleep(0); 

Application.ProcessMessages(); // clear all Vcl messages // part of Vcl.Forms 
CheckSynchronize(); // check all threaded events 
Cuestiones relacionadas