Laden...

Sinnvoller Einsatz des Producer Consumer Patterns

Erstellt von Rioma vor 8 Jahren Letzter Beitrag vor 8 Jahren 1.838 Views
R
Rioma Themenstarter:in
228 Beiträge seit 2013
vor 8 Jahren
Sinnvoller Einsatz des Producer Consumer Patterns

Hallo zusammen,

ich spiele seit einiger Zeit mit der TPL - Dataflow library rum und habe eine wahrscheinlich sehr triviale Frage.

Bei welchen Szenarien ist das Producer Consumer Pattern Sinnvoll?

Ich habe ein "real world" Beispiel gesehen, bei dem Bilder konvertiert wurden. Eingesetzt wurde die Blockingcollection.

Es wurde eine Anzahl an Bildern ausgewählt, ein Task hat die Bilder in eine Warteschlange gepusht und 4 Tasks haben entnommen und Konvertiert.

Meiner Meinung nach, hätte man dies auch Problemlos mit einer normalen (Parallelen)Schleife lösen können. Ich erkenne hier einfach nicht den Vorteil.

Würden nach und nach Bilder in ein Verzeichnis gespielt werden und diese automatisiert Konvertiert werden sollen, hätte ich es schlüssiger gefunden, da es viel mehr nach einer Pipeline aussieht.

Könntet ihr mir kurz erklären, wann ihr euch für Producer Consumer entscheidet, bzw. wann der Einsatz wirklich Sinnvoll ist?

16.830 Beiträge seit 2008
vor 8 Jahren

Vermutlich hast Du TPL Pipelines gesehen; und die Bilder (zB Figure 4) zeigen die Gründe relativ deutlich.

Der Vorteil ist die Skalierbarkeit.

zB kannst Du für das Rendern von Bildern 5 Tasks nehmen, weil das sehr aufwändig ist und für das Speichern der Bilder nur 2 Tasks, da das sehr schnell geht.
Mit einer parallelen Schleife geht das nicht. Dort kannst Du nur den kompletten Prozess durch einen neuen Task erweitern aber Du kannst damit keine Bottlenecks lösen.

Das bietet sich bei allen Workflows an, deren Arbeitsschritte unterschiedliche Aufwände darstellen.

Weitere Gründe sich die Abkapselung, zB aufgrund von Berechtigungen oder verschiedenen Schichten.

6.911 Beiträge seit 2009
vor 8 Jahren

Hallo Rioma,

Bei welchen Szenarien ist das Producer Consumer Pattern Sinnvoll?

Ich gehe davon aus, dass du weißt was Producer-Consumer ist und was es bedeutet, aber dennoch schreib ich das hier etwas ausführlicher da ich glaube dir so die Anwendungsfälle schon zeigen zu können.

Ein Producer-Consumer kann verwendet werden um ein Multi-Prozess-Synchronisations-Problem zu lösen, indem er die Prozesse welche Daten produzieren und die Prozesse welche die Daten konsumieren entkoppelt. Zum Entkoppeln und zur "Kommunikation" von Producer und Consumer wird ein Buffer (meist ein FiFo-Speicher, Warteschlange) verwendet. Somit ermöglicht der Producer-Consumer eine gepufferte Kommunikation zwischen den beteiligten Prozessen.

Anders ausgedrückt kann ein Producer-Consumer auch so gesehen werden, dass die "parallelen Schleifen" in zwei Gruppen aufgebrochen: die Produzenten und die Konsumenten, wobei die Ausgaben der Produzenten die Eingaben der Konsumenten sind und somit die Reihenfolge der abgearbeitenden Elemente erhalten bleibt. Ein Producer-Consumer stellt somit eine Pipeline dar und ähnelt einem Fließband in der industriellen Fertigung.

Parallele Schleifen ähneln dem Producer-Consumer in der Hinsicht, dass die Daten parallel verarbeitet werden, haben aber den (entscheidenden) Nachteil, dass keine neuen Daten während der Abarbeitung der Liste hinzugefügt werden können. Beim Producer-Consumer kann der Producer (dem Buffer) Daten hinzufügen und die tatsächliche Abarbeitung findet im Consumer statt. Dadurch kann der Consumer die Daten mit "seiner" Geschwindigkeit verarbeiten, während der Producer zeitgleich Daten (dem Buffer) hinzufügen kann.

Z.B. ist [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke) auch ein Producer-Consumer-Szenario, denn der Producer (=Delegat für die UI-Aktion) stellt dem Consumer (=UI-Loop) eine Aufgabe zur Abarbeitung zur Verfügung. Dies könnte per paralleler Schleife nicht gelöst werden - zumindest nicht ohne dass das GUI mächtig blockiert.
Auch Maus- und Tastatureingaben werden als Producer-Consumer vom Betriebssystem verarbeitet.

Anwendbar ist eine Producer-Consumer od. eine Pipeline immer dann, wenn die Daten in der Eingangsreihenfolge parallel - wenn auch zeitversetzt - verarbeitet werden sollen und die Möglichkeit zum Hinzufügen von neuen Daten während der Abarbeitung bestehen soll.

Meiner Meinung nach, hätte man dies auch Problemlos mit einer normalen (Parallelen)Schleife lösen können.

Parallele Schleifen sind dafür gedacht unabhängige Operationen auf eine Liste von Elementen durchzuführen, wobei die Reihenfolge der Abarbeitung egal ist. Sobald eine dieser beiden Einschränkungen nicht auf die Aufgabenstellung passt, so ist die parallel Schleife nicht (richtig) anwendbar.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

W
872 Beiträge seit 2005
vor 8 Jahren

Das Producer/Consumer Pattern dient auch oft zur Entkoppelung.
Mit einer Schleife bist Du nicht enkoppelt.
Ein Producer ist einfach ein logischer Block, der nicht weiß, was verschiedene Consumer-Implementierungen damit machen.

R
Rioma Themenstarter:in
228 Beiträge seit 2013
vor 8 Jahren

Danke für die ausführlichen Antworten. Ich werde mich darauf aufbauend erstmal weiter damit beschäftigen.