Ich brauche bei solchen für mich neuen Dingen meist ein wenig länger, deswegen hoffe ich, dass mir hier geholfen werden kann... .
Ich möchte 2 Sockets (TCP, UDP) Daten holen lassen. Das sind Packete, die Anfänglich ein längen byte haben. Diese Strukturen sollen von einem Consumer weiterverarbeitet werden.
Nun dachte ich zuerst an ein buffer, an den die 2 Producer anhängen und den der Consumer abarbeitet. Wenn das aber synchron ablaufen soll, müsste der Consumer nach jedem eingelesenen Paket, die Daten alle wieder an den Anfang kopieren. Ich habe einige Überlegungen, die ich nicht weiter ausweiten möchte. Ist es sinnvoll, die eine Weile zu warten, bis der Buffer einige Daten gesammelt hat, um ihn dann für den Consumer zu kopieren und neu anzufangen?
Ich hoffe ihr versteht mein Problem und könnt mir weiterhelfen. Ich habe hier auch schon gesucht, aber alles gefundene, kann ich nicht wirklich auf meine Sache ummünzen. Auch in den trolltech Beispielen habe ich geschaut und einige Techniken wie SharedData gefunden, wo ich aber auch nicht weiß, ob das so das wahre ist.
Threads Producer und Consumer - Techniken
Ohja, hab mir mal ein paar Implementierungssachen angeschaut. Eigentlich ganz klar:
Die 2 Producer holen die Daten und fügen sie an den Ringbuffer an. Der Consumer durchläuft ihn und man muss nur aufpassen, dass der Consumerindex von hinten nie überholt wird.
Ich glaube das ist was ich brauche, danke
Die 2 Producer holen die Daten und fügen sie an den Ringbuffer an. Der Consumer durchläuft ihn und man muss nur aufpassen, dass der Consumerindex von hinten nie überholt wird.
Ich glaube das ist was ich brauche, danke
Mir fällt dazu gerade noch etwas ein. Ich habe die Implementierung angefangen und zwar übergebe ich einen Zeiger auf die Consumerklasse in die beiden Producer-thread-klassen. Von dort aus schreibe ich die Daten in den Consumer per Setter-Methode.
Ist das richtig, dass die Methode dann von dem jeweiligen thread ausgeführt wird oder von dem thread des Consumers? Das ich die ganzen Funktionen synchronisieren muss, ist mir bewusst. Ich weiß nur nicht, ob ich es per Setter Methode machen kann.
Ist das richtig, dass die Methode dann von dem jeweiligen thread ausgeführt wird oder von dem thread des Consumers? Das ich die ganzen Funktionen synchronisieren muss, ist mir bewusst. Ich weiß nur nicht, ob ich es per Setter Methode machen kann.
Hallo,
wenn ich Deine beschreibung richtig verstanden habe, dann sollte das so nicht klappen.
Vorausgesetzt du machst in den Setter-Methoden auch die Verarbeitung, dann sollte die verarbeitung weiterhin im Kontext des Producers erfolgen und nicht im Consumer.
Hier mal eine allgemein gehaltene Möglichkeit das Consumer-Producer Problem anzugehen. Ich denke das kannst du auf Deine Anforderungen anpassen.
Ich würde es so machen:
* Eine zentrale Queue die alle kennen. Die Queue könnte z.B. eine QList mit Pointern auf eine Daten-Klasse von Dir sein.
* Producer erzeugt Daten und wirft diese in eine Queue (QList::append(...)).
* Die Consumer hängen permanent in QThread::run() und legen sich schlafen, wenn es nichts zu tun gibt (Queue ist leer), bleiben aber im run().
* Sobald ein Consumer Arbeit in der Queue findet (QList::size() > 0) holt er sich das Arbeitspaket (QList::takeFirst()) und verarbeitet es. Was du mit dem Ergebnis machst musst du dann wissen.
Ich hoffe das bringt Dich ein wenig weiter
Ciao,
Sephral
wenn ich Deine beschreibung richtig verstanden habe, dann sollte das so nicht klappen.
Vorausgesetzt du machst in den Setter-Methoden auch die Verarbeitung, dann sollte die verarbeitung weiterhin im Kontext des Producers erfolgen und nicht im Consumer.
Hier mal eine allgemein gehaltene Möglichkeit das Consumer-Producer Problem anzugehen. Ich denke das kannst du auf Deine Anforderungen anpassen.
Ich würde es so machen:
* Eine zentrale Queue die alle kennen. Die Queue könnte z.B. eine QList mit Pointern auf eine Daten-Klasse von Dir sein.
* Producer erzeugt Daten und wirft diese in eine Queue (QList::append(...)).
* Die Consumer hängen permanent in QThread::run() und legen sich schlafen, wenn es nichts zu tun gibt (Queue ist leer), bleiben aber im run().
* Sobald ein Consumer Arbeit in der Queue findet (QList::size() > 0) holt er sich das Arbeitspaket (QList::takeFirst()) und verarbeitet es. Was du mit dem Ergebnis machst musst du dann wissen.
Ich hoffe das bringt Dich ein wenig weiter
Ciao,
Sephral
Hi,
QQueue hab ich mir z.B. auch angesehen. In dem anderen Fall mit den Setter Methoden habe ich mir gedacht, die Pakete in den Puffer zu schreiben und jeweils einen Index für das abarbeiten und für das reinschreiben zu haben. Dazu noch eine Anzahl an Bytes, die der Consumer abarbeiten kann.
In der Setter Methode soll natürlich nichts verarbeitet werden, sondern lediglich die Daten reingefüllt werden. Ich will das so machen, damit ich mich nicht mit mutex und indizes in jedem Thread totwerfe
Aber ich werde nochmal über dein Vorschlag nachdenken, bei der Queue ist es nur schade, dass ich in dem Fall keinen festen Typ habe.
QQueue hab ich mir z.B. auch angesehen. In dem anderen Fall mit den Setter Methoden habe ich mir gedacht, die Pakete in den Puffer zu schreiben und jeweils einen Index für das abarbeiten und für das reinschreiben zu haben. Dazu noch eine Anzahl an Bytes, die der Consumer abarbeiten kann.
In der Setter Methode soll natürlich nichts verarbeitet werden, sondern lediglich die Daten reingefüllt werden. Ich will das so machen, damit ich mich nicht mit mutex und indizes in jedem Thread totwerfe
Aber ich werde nochmal über dein Vorschlag nachdenken, bei der Queue ist es nur schade, dass ich in dem Fall keinen festen Typ habe.
Hallo CLRS530,
mit "Queue" meine ich nicht zwingend eine QQueue. Ich verwende meist QLists mit mit Pointern auf eigene Kommando- und Datenhaltungs-Objekte. Das hat sich bei mir wunderbar bewährt wenn es darum geht Threads mit Arbeit zu versorgen.
Die Objekte die ich in die Listen packe beinhalten meist ein Kommando das dem Thread sagt, was er machen soll und zusätzlich natürlich Daten zum Verarbeiten.
Ciao,
Sephral
mit "Queue" meine ich nicht zwingend eine QQueue. Ich verwende meist QLists mit mit Pointern auf eigene Kommando- und Datenhaltungs-Objekte. Das hat sich bei mir wunderbar bewährt wenn es darum geht Threads mit Arbeit zu versorgen.
Die Objekte die ich in die Listen packe beinhalten meist ein Kommando das dem Thread sagt, was er machen soll und zusätzlich natürlich Daten zum Verarbeiten.
Ciao,
Sephral