2011-11-11 23 views
11

quello che sarebbe un buon modo per risolvere il seguente problema in Qt:dati multithread pipeline di elaborazione in Qt

Ho una classe sensore, che produce continuamente i dati. Su questi dati, devono essere eseguite diverse operazioni dopo l'altra, il che può richiedere parecchio tempo. Per questo ho alcune classi aggiuntive. Fondamentalmente, ogni volta che viene registrato un nuovo elemento di dati, la prima classe dovrebbe ottenere i dati, elaborarli, passarli al successivo e così via.

sensore -> classe 1 -> ... -> ultima classe

voglio mettere le singole classi del gasdotto nelle loro discussioni, in modo che la classe 1 può già lavorare sul campione n +1 quando la classe 2 sta elaborando il campione n ...

Inoltre, poiché i singoli passaggi possono differire notevolmente nelle loro prestazioni (ad esempio il sensore è molto più veloce degli altri) e non sono interessato a dati obsoleti, I vuoi che la classe 1 (e tutto il resto) per ottenere sempre i dati più recenti dal loro predecessore, scartando i vecchi dati. Quindi, nessun grande buffer tra i passaggi della pipeline.

Prima ho pensato di utilizzare Qt :: QueuedConnections per segnali/slot, ma suppongo che questo introdurrebbe una coda piena di campioni obsoleti in attesa di essere elaborati dalle parti più lente della pipeline?

risposta

3

Quello con cui si ha a che fare è un modello consumer del produttore. Puoi trovare una panoramica generale di questo qui. http://en.wikipedia.org/wiki/Producer-consumer_problem

Si desidera utilizzare un QMutex per limitare l'accesso ai dati a un thread alla volta. Utilizzare QMutexLocker per bloccarlo.

Per un esempio molto semplificato:

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

Basta creare la propria classe "coda" a un elemento. Esso dovrebbe avere:

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

La funzione "accodamento" è solo:

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

La funzione "dequeue" è solo:

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

Il tipo di dati può essere un modello parametro.

Problemi correlati