Multithreaded programmieren mit QWaitCondition

Alles rund um die Programmierung mit Qt
Antworten
mnagl
Beiträge: 1
Registriert: 14. Oktober 2008 18:39

Multithreaded programmieren mit QWaitCondition

Beitrag von mnagl »

Ist es möglich QWaitCondition.wait() in einer Methode eines Objekts aufzurufen, das von mehreren Threads angesprochen wird, um diese aufrufenden Threads warten zu lassen?

Code: Alles auswählen

class PacDataQueue
{
  public:
    ....
    void enqueue(PacWaveformChunk *w);
    PacWaveformChunk * dequeue()
    {
      mutex.lock();
      waitForData.wait(&mutex);
      if (q.isEmpty())
        return 0;
      return q.dequeue();
      mutex.unlock();
    }
  private:
    QQueue<PacWaveformChunk*> q;
    QMutex mutex;
    QWaitCondition waitForData;
};

PacDataQueue dataqueue;

class PacAnalyzerThread : public QThread
{
    Q_OBJECT
  public:
    ...
    void run()
    {
      PacWaveformChunk *data;
      forever {
        data=dataqueue.dequeue();
        processData(data);
      }
    }
};
Ginsengelf
Beiträge: 79
Registriert: 2. Mai 2007 10:21

Re: Multithreaded programmieren mit QWaitCondition

Beitrag von Ginsengelf »

mnagl hat geschrieben:Ist es möglich QWaitCondition.wait() in einer Methode eines Objekts aufzurufen, das von mehreren Threads angesprochen wird, um diese aufrufenden Threads warten zu lassen?

Code: Alles auswählen

    PacWaveformChunk * dequeue()
    {
     (...)
      return q.dequeue();
      mutex.unlock();
    }
Moin, prinzipiell könnte das funktionieren, Versuch macht kluch, denke ich.
Aber: dein Mutex wird hier nie entsperrt, wenn das return davor kommt. Du könntest hier mit einem QMutexLocker arbeiten, der entsperrt das entsprechende Mutex, wenn der seinen Gültigkeitsbereich verlässt.

Ginsengelf

edit: du kriegst ein Problem, wenn mehrere Threads warten, dann geweckt werden, und jeder dequeue() aufruft, aber weniger Elemente als Threads da sind!
Superheftig
Beiträge: 63
Registriert: 6. September 2008 15:20

Beitrag von Superheftig »

Der code sollte so aussehen

class PacDataQueue
{
public:
....
void enqueue(PacWaveformChunk *w) {
QMutexLocker locker(&mutex);
while (queue.size() > irgendein Maximum) {
queueFull.wait(&mutex);
}
q.enqueue(w);
waitForData.wakeAll();
}
PacWaveformChunk * dequeue()
{
QMutexLocker locker(&mutex); // Immer nen mutexlocker benutzten - sicherer
while (q.isEmpty()) {
waitForData.wait(&mutex); // Thread schlafen legen falls queue leer ist
}
q.dequeue();
queueFull.wakeAll();
}
private:
QQueue<PacWaveformChunk*> q;
QMutex mutex;
QWaitCondition waitForData;
QWaitCondition queueFull;
};


Damit können jetzt beliebig viele Threads sowohl lesen also auch schreiben ohne deadlocks und fehler in der synchronisation.
Deine Frage versteh ich allerdings nichts so ganz
Antworten