LabVIEWForum.de
Unterschied Design Pattern - Druckversion

+- LabVIEWForum.de (https://www.labviewforum.de)
+-- Forum: LabVIEW (/Forum-LabVIEW)
+--- Forum: LabVIEW Allgemein (/Forum-LabVIEW-Allgemein)
+---- Forum: Datenkommunikation (/Forum-Datenkommunikation)
+---- Thema: Unterschied Design Pattern (/Thread-Unterschied-Design-Pattern)

Seiten: 1 2


Unterschied Design Pattern - Mechatroniker28 - 05.07.2018 14:20

Hallo LabVIEW-Team,

Was ist der Unterschied zwischen Queued Message Handler, Ereignistruktur und Producer Consumer?
Ich will wissen welche Architektur für welche Bereich geeignet ist?
Ich bedanke mich im Voraus.

Viele Grüße
Mechatroniker28


RE: Unterschied Design Pattern - IchSelbst - 07.07.2018 13:16

(05.07.2018 14:20 )Mechatroniker28 schrieb:  Was ist der Unterschied zwischen Queued Message Handler, Ereignistruktur und Producer Consumer? Ich will wissen welche Architektur für welche Bereich geeignet ist?

"Queued Message Handler": QMH
QMH ist, wie der Name besagt, ein System, dass Messages mittels Queues handhabt. QMH ist immer Mittel zum Zweck. Ein Zweck z.B. ist die Producer-Consumer-Strategie.

Hauptzweck einer Queue besteht darin, unabhängige Programmmodule logisch zu verbinden. Jedes einzelne Modul für sich alleine arbeitet quasi selbstständig - strenggenommen ohne zu wissen (ohne wissen zu müssen) wer sonst noch irgendwo arbeitet. Da aber jedes Modul etwas produziert (ein Modul, das nichts produziert, ist zuerst einmal sinnlos), ist es sinnvoll, dass das Modul zum einen diese Daten nach außen geben kann, zum anderen ist es sinnvoll, das das Modul von außen gesteuert werden kann. Vom Modul aus gesehen ist das Außen ein anderes Modul. Die Schnittstelle zwischen den einzelnen Modulen kann man mit Queues realisieren (und/oder Meldern, die als Sonderfall einer Queue angesehen werden können).

Ganz wichtig: Eine Queue hat immer eine Richtung - nämlich vom "Producer" zum "Consumer": Ersterer schreibt Daten in die Queue (versendet also Daten per Queue), Letzterer ließt die Date aus der Queue aus (empfängt also Daten per Queue). Diese Richtungsgebundenheit bedeutet natürlich, dass zum Verbinden zweier Module in der Regel zwei Queues notwendig sind.


"Producer Consumer"
Auch hier gilt: selbsterklärend. Irgendwer produziert etwas, ein anderer konsumiert dieses Etwas. Das Etwas nun muss also vom Produzenten zum Verbraucher (warum sollte es sonst produziert werden). Der Weg, den das Etwas nimmt, heißt Queue.
Beispiel (also Bereich): Das Datenerfassungsmodul "AIn" produziert Daten (Messwerte) dadurch, dass Werte aus dem DAQmx gelesen werden. Diese Daten stellt das Modul sozusagen der Allgemeinheit zur Verfügung - indem es die Daten in eine Queue (kann auch ein Melder sein) schreibt. Wer die Daten haben will, soll sie aus der Queue (dem Melder) herausholen.
"Daten", also das, was in der Queue gehandhabt wird, müssen nicht unbedingt Daten in Form von Messwerten sein. "Daten" können auch Kommandos oder Mitteilungen ("Message") sein. Der Consumer (von Messwerten) sagt z.B. dem Producer (der Messwerte), dass er (der Producer) diese oder jene Kanäle sampeln soll. Das sagt der Consumer selbstverständlich per Queue.

Hinweis:
"Producer/Consumer" kann man im engeren Sinne auf Queues beziehen und im weiteren Sinne auf Module.


"Ereignistruktur"
Das Element "Ereignistruktur" nehme ich immer dann, wenn der Anwender über die GUI eine Eingabe in das System machen will. Eine solche Eingabe ist immer eine einmalige Sache, also ein "Ereignis". Ein Ereignis soll aber immer eine Wirkung haben - z.B. das Starten der Abtastung von Messwerten im AIn-Modul. In dem Ereignis-Case würde man also in eine Queue schreiben, die das AIn-Modul veranlasst, ab jetzt Daten zu samplen.


Fazit:
Das Programm wird aufgeteilt in viele unabhängige Module, die untereinander per Queue/Melder kommunizieren. Die Kommunikation des Anwenders mit den Modulen geschieht am Schnittpunkt "Ereignisstruktur".


Änderungshinweis:
Da war ja ein ganzer Absatz doppelt - blödes Ctrl-V ...


RE: Unterschied Design Pattern - Lucki - 08.07.2018 07:52

IchSelbst hat das ja sehr schöne erklärt, nur noch eine kleine Ergänzung: Das Entscheidende ist, dass Erzeuger und Verbraucher nicht synchron laufen müssen. (oder man könnte auch sagen: Die Synchronisation besorgt die Struktur selbst). Der Erzeuger muß mit der Erzeugung neuer Daten nicht warten, bis die vorherigen Daten verarbeitet worden sind, und der Verbraucher muß nicht befürchten (falls der Erzeuger mit der Erzeugung neuer Daten nicht wartet), daß Daten verloren gehen. wenn er die Daten nicht schnell genug abholt. Natürlich funktioniert das Ganze dauerhaft nur dann, wenn der Verbaucher mit der Verarbeitung der Daten im Schnitt einen Tick schneller ist als der Erzeuger mit der Erzeugung derselben. (Der Verbraucher braucht aber kein Wait in seiner Schleife, das Wait macht die Queuefunktion selbst. Wenn beim Versuch, neue Daten abzuholen, noch keine oder nicht genügend Daten in der Queue sind, wird an der Datenabholfunktion gewartet, bis die Bedingung erfüllt ist)


RE: Unterschied Design Pattern - Achim - 10.07.2018 14:39

@ IchSelbst:

Sehr schön geschrieben!
Guru1


Das sollte FÜR IMMER auf die Startseite des LVF!Dafuer


RE: Unterschied Design Pattern - Mechatroniker28 - 10.07.2018 14:49

Hallo LabVIEW-Team,

vielen Dank für die Antwort "Ichselbst". Was meinst du mit "AIn"? Ist das nur ein name?
Lucki, auf welche Design Pattern beziehst du dich?

Viele Grüße
Mechatroniker28


RE: Unterschied Design Pattern - jg - 10.07.2018 16:14

AIn = Analog In

Gruß, Jens


RE: Unterschied Design Pattern - IchSelbst - 10.07.2018 21:15

(10.07.2018 14:49 )Mechatroniker28 schrieb:  Lucki, auf welche Design Pattern beziehst du dich?
Er bezieht sich auf das Design Pattern "Producer Consumer?": Producer = Erzeuger. Consumer = Verbraucher.

Lucki beschreibt einen wichtigen Vorgang: Wie synchronisiere ich die Daten verschiedener Module, die selbst asynchron arbeiten sollen. Auch hier fällt mir ein Beispiel ein: Supermarkt (= Queue). Frühmorgens (also asynchron zur Kundschaft, die einkauft) kommt der große LKW und bringt (= Schreiben in die Queue) neue Ware ("Daten"). Im Laufe des Tages kommt dann die Kundschaft (asynchron zum LKW) und macht den Laden wieder leer (Lesen aus der Queue). Kommt keine Kundschaft aber der LKW, läuft der Laden über …

Gegenmodel: Fahrender Bäcker auf dem Dorf. Ohne Queue hackt die Sache: Der Kunde muss sich beim LKW einfinden, genau zu dem Zeitpunkt, wenn der LKW da ist - also synchron. Kommt der Kunde später, ist der LKW weg und der Kunde bekommt keine Brötchen. Kommt der LKW zu spät, kommt der Zeitplan des Kunden durcheinander, weil er unerwarteterweise warten muss.

Fazit:
Mit Queues kann man hervorragend zwischen zwei asynchronen Abläufen Daten austauschen.


RE: Unterschied Design Pattern - Mechatroniker28 - 13.07.2018 14:55

Vielen Dank Ichselbst,

was für Vorteile würde es noch geben, wenn man Ereignisstrukuturen für GUI`s verwendet?
Ich bedanke mich im Voraus.

Viele Grüße
Mechatroniker28


RE: Unterschied Design Pattern - jg - 13.07.2018 16:26

Da gibt es doch gar keine Diskussion. Sobald ich ein VI habe, welches eine GUI-Interaktion seines Frontpanels behandeln soll, habe ich da eine Event-Struktur drinnen. Das macht das Programmieren viel einfacher.

Gruß, Jens


RE: Unterschied Design Pattern - IchSelbst - 13.07.2018 22:10

(13.07.2018 14:55 )Mechatroniker28 schrieb:  Was für Vorteile würde es noch geben, wenn man Ereignisstrukturen für GUI`s verwendet?
Da eine Ereignisstruktur zum richtigen Programmieren dazu gehört, ist es nicht vorteilhaft sie zu verwenden, sondern von Nachteil, sie nicht zu verwenden.

Die Inhalte der meisten Ereignis-Cases kann man bestimmt auch ohne Ereignissequenz handhaben, also in einem ganz normalen Datenfluss bearbeiten.

Aber:
Da du die vielen Inhalte der Cases dann nicht mehr gestapelt hast, verbrauchen die Inhalte der Cases entsprechend viel Platz im Blockdiagramm. Das aber wird mit der Zeit, also im Laufe der Programmerstellung, wenn immer neue Elemente dazukommen, unübersichtlich - sprich nicht debugbar: 1. fataler Programmierfehler. Jetzt könntest du sagen, dann machst du halt eine Case-Sequenz, dann ist es wieder übersichtlich - dann sage ich: das wäre ja schon fast die Ereignissequenz.

Zweitens:
Meistens will man eine Operation nach einer Wertänderung ausführen, sobald der Cursor das Eingabeelement verlässt. Dieses aber in einem Datenfluss festzustellen ist bei manchen Eingabeelementen nicht so einfach. Wenn du eine Wertänderung feststellen willst, musst du den vorherigen Wert mit dem jetzigen Wert vergleichen. Das aber würde einen Rückkopplungsknoten im Datenfluss bedeutet. Das Erkennen der Wertänderung ist aber (schon seit beinahe Urzeiten) eine Eigenschaft eines jeden Eingabeelementes. Die Ereignissequenz ist also ein Mittel zum Ausnutzen vorhandener (wenn auch unsichtbarer) Funktionalitäten. Mit Ereignissequenz sparst du also Programmieraufwand.

Drittens:
Da du ohne Ereignissequenz einen kontinuierlichen Datenfluss hast, verbraucht du automatisch auch Prozessorzeit. Das scheint zwar bei modernen Prozessoren irrelevant - das kommt aber darauf an, wie der Rest des Programmes gestaltet ist. Im schlimmsten Falle kommt es zu unvorhergesehenen (und unvorhersehbaren) Ereignissen, die auch wieder ein Debuggen schwierig machen.

Hinweis:
Immer pro VI nur eine einzige Ereignisstruktur verwenden. Mehr braucht man auch nicht. Wer mehr braucht, hat einen strukturellen Fehler im Programm ...