Threads Producer und Consumer - Techniken

Alles rund um die Programmierung mit Qt
Antworten
CLRS530
Beiträge: 155
Registriert: 8. Oktober 2007 18:00

Threads Producer und Consumer - Techniken

Beitrag von CLRS530 »

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.
Zandru
Beiträge: 84
Registriert: 29. Mai 2007 15:35

Beitrag von Zandru »

Dazu fällt mir ein Stichwort ein: Ringbuffer
CLRS530
Beiträge: 155
Registriert: 8. Oktober 2007 18:00

Beitrag von CLRS530 »

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 :-)
Zandru
Beiträge: 84
Registriert: 29. Mai 2007 15:35

Beitrag von Zandru »

gern geschehn :D
CLRS530
Beiträge: 155
Registriert: 8. Oktober 2007 18:00

Beitrag von CLRS530 »

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.
Sephral
Beiträge: 201
Registriert: 1. Februar 2006 09:40
Kontaktdaten:

Beitrag von Sephral »

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
CLRS530
Beiträge: 155
Registriert: 8. Oktober 2007 18:00

Beitrag von CLRS530 »

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.
Sephral
Beiträge: 201
Registriert: 1. Februar 2006 09:40
Kontaktdaten:

Beitrag von Sephral »

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
Antworten