2011-11-11 8 views
11

lo que sería una buena manera de resolver el siguiente problema en Qt:de datos de varias hebras de procesamiento de tubería en Qt

que tienen una clase de sensor, que produce continuamente datos. En estos datos, varias operaciones deben realizarse después de otra, lo que puede llevar bastante tiempo. Para esto tengo algunas clases adicionales. Básicamente, cada vez que se graba un nuevo elemento de datos, la primera clase debe obtener los datos, procesarlos, pasarlos a la siguiente y así sucesivamente.

sensor -> clase 1 -> ... -> última clase

quiero poner las clases individuales de la tubería en sus propios hilos, de modo que la clase 1 ya se puede trabajar en la muestra n +1 cuando la clase 2 está procesando la muestra n ...

Además, como los pasos individuales pueden diferir en gran medida en su rendimiento (por ejemplo, el sensor es mucho más rápido que el resto) y no me interesan los datos obsoletos, quiere que la clase 1 (y todo lo que le sigue) obtenga siempre los datos más nuevos de su predecesor, descartando los datos antiguos. Entonces, no hay un gran buffer entre los pasos de la tubería.

Primero pensé en usar Qt :: QueuedConnections para señales/ranuras, pero supongo que esto introduciría una cola llena de muestras obsoletas esperando a ser procesadas por las partes más lentas de la tubería.

Respuesta

3

Lo que está tratando es un patrón de consumidor de productor. Puede encontrar una descripción general de eso aquí. http://en.wikipedia.org/wiki/Producer-consumer_problem

Desea utilizar un QMutex para limitar el acceso a los datos a un hilo a la vez. Use QMutexLocker para bloquearlo.

Para un ejemplo muy simplificado:

QList<quint32> data; 
QMutex mutex; 

// Consumer Thread calls this 
int GetData() 
{ 
    quint32 result(-1); // if =1 is a valid value, you may have to return a bool and 
         // get the value through a reference to an int 
         // in the parameter list. 

    QMutexLocker lock(&mutex); 

    if (data.size()) 
    { 
     result = data.front(); // or back 
     data.clear(); 
    } 

    return result; 
} 

// Producer Thread calls this 
void SetData(quint32 value) 
{ 
    QMutexLocker lock(&mutex); 

    data.push_back(value); 
} 
5

Simplemente construya su propia clase de "elemento de cola" de un elemento. Debe tener:

A piece of data (or pointer to data) 
A Boolean "dataReady" 
A mutex 
A condition variable 

La función "en cola" es simplemente:

lock mutex 
Replace data with new data 
dataReady = true 
signal condition variable 

La función de "quitar de la cola" es simplemente:

lock mutex 
while (!dataReady) cond_wait(condition, mutex) 
tmpData = data 
data = NULL (or zero) 
dataReady = false 
unlock mutext 
return tmpData 

El tipo de los datos puede ser una plantilla parámetro.

Cuestiones relacionadas