LabVIEWForum.de - Parallele Schleifen mit Queues richtig beenden

LabVIEWForum.de

Normale Version: Parallele Schleifen mit Queues richtig beenden
Du siehst gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
Hallo,

ich habe ein Programm, welches im Wesentlichen aus zwei parallelen While-Schleifen besteht. Während die erste Schleife dazu dient Daten einzulesen, ist die zweite Schleife für die Datenverarbeitung, graphische Darstellung usw. gedacht. Das Einlesen ist oftmals schneller als die Weiterverarbeitung. Aus diesem Grund findet der Transfer der Daten zwischen den Schleifen mit Hilfe der QUEUE-VIs statt. Das Prinzip funktioniert soweit.

Die Lese-Schleife läuft eine bestimmte Zeit (z.B. 5 Sekunden) und wird dann beendet. Wie kann ich nun die zweite Schleife dazu bringen ebenfalls zu stoppen? Und zwar so, dass die Anzahl der Schleifendurchläufe für beide While-Schleifen gleich groß ist. Momentan ist es nämlich so, dass die zweite Schleife immer einen Durchlauf mehr macht.

Ich habe versucht, das Problem im angehängten VI auf das Wesentliche zu reduzieren.

Vielen Dank schonmal
Hallo Labrat,

zuerst mal eine kleine Frage. Wieso sollen denn die beiden Schleifen genau gleich oft druchlaufen werden? Eventuell wäre das Producer-Consumer Pattern für dich sehr hilfreich sein. Wenn du dann nicht "nur" die Daten, sondern auch noch Steuerbefehle und in der zweiten Schleife eine Case-Struktur verwendest, dann könntest du auch beide Schleifen beenden.

MfG Carsten
Hallo,

einfach abfragen, ob noch ein Wert gesendet werden soll, oder nicht:

[attachment=38423]

Die Queue musst du auch nur 1mal destroyen Wink

Generell sei hier auf das Producer-Consumer-Design-Pattern verwiesen.




Beste Grüße,
NWO
Wenn du die "Speicher-Schleife" dadurch abbrechen willst, dass du die Queue zerstörst und somit der Fehler einen Abbruch der Schleife erzeugt, dann ist das ein durchaus übliches Vorgehen. Und dann ist es auch völlig normal, dass du in der "Speicher-Schleife" einen Durchlauf mehr hast, nämlich den Durchlauf, der dir einen Fehler ausgibt.

Allerdings würde ich noch eine Fehlerbehandlung einbauen. Nur wenn kein Fehler vorliegt, wird eine Verarbeitung der Daten vorgenommen, ansonsten nicht. In etwa so:

[attachment=38425]

Ansonsten, s. oben.

Gruß, Jens
Beim Vorshlag von NWO hat man zwar die gleiche Anzahl von Schleifendurchläufen, aber ansonten ist es suboptimal:
Bei 10 Schleifendurchläufen werden 9 Werte gesendet, aber außer diesen 9 Werten wird unten noch 1 ungültiger Wert "0" empfangen.
Schließe mich dem Vorschlag von Jens an. Wirklich professionell ist die Methode sowieso nicht, aber es ist einfach und funktioniert. So ein kleiner Nebeneffekt muß da eben in Kauf genommen werden.
Weitere Unschönheiten des VIs sind: (a) das überflüssige Wait in der unteren Schleife, (b) das zweite Zerstören der Queue an der unteren Schleife, nachdem das an der oberen Schleife schon passiert ist.

[attachment=38429]

Edit: Falls es interessiert. Hier noch das entsprechende "Profi"-Beispiel, bei dem alles so funktioniert wie es sollte - keine unterschiedlichen Schleifenanzahlen, keine Case-Unterscheidung von gültigen und ungültigen Daten, keine missbrauchten Errormeldungen.
[attachment=38434]
[attachment=38462]
Vielen Dank für eure Vorschläge. ich habe alle getestet (sogar die Profi-Lösung), leider ohne Erfolg. Um mein Problem zu schildern muss ich etwas weiter ausholen. Im Prinzip geht es um Bildbearbeitung. Die erste Schleife dient dazu ein Bild von einer Kamera zu holen; die zweite Schleife zur Bildbearbeitung. Die beide Schleifen müssen gleich oft durchlaufen werden, da ich sonst beim letzen - und nur beim letzten - Schleifendurchlauf in der Bearbeitungs-Schleife folgende Fehlermeldung bekomme:

"Fehler 1 bei Element aus Queue entfernen"
"NI Vision: Kein Bild"

Es scheint fast so, als ob die zweite Schleife die erste überholen würde. Ist das überhaupt möglich?

Ich habe versucht, im angehängten VI das Problem wieder auf das Wesentliche zu reduzieren. Leider ist dafür jedoch das NI Vision Modul erforderlich.

Anmerkung: Mir ist klar, dass ein Schleifendurchlauf ohne Zeitverzögerung immer kritisch zu beäugen ist, jedoch konnte ich in dieser abgespeckten Version nur so den/die Fehler rekonstruieren. Im Original-Programm habe ich bereits verschiedene Varianten mit Verzögerungen ausprobiert. Alle ohne Erfolg

Vielen Dank für eure Hilfe
Habe in meinen letzten Beitrag das VI noch angehängt.
So wie Du es hast kann es nicht funktionieren: Die Queue wird wahrscheinlich (Wettlaufeffekt) zerstört, bevor die untere Schleife das letzte Mal ausgeführt wird. Also "Queue beenden" an die untere Schleife anhängen!
Hi,

wenn du die Fehler zusammenführst klappt alles so wie du willst.

Gruß Ome
Ah Ok, vielen Dank. Ich glaube man merkt, dass ich zum ersten mal mit Queues arbeite. Inzwischen konnte ich jedoch eine merkwürdige Beobachtung machen:

Ich habe die erste While-Schleife durch eine for-Schleife ersetzt, sodass beide 500mal durchlaufen werden. In der zweiten Schleife habe ich eine Verzögerung eingebaut, sodass diese deutlich langsamer läuft als die Erste. Dies entspricht auch den Verhältnissen in meinem Hauptprogramm. Nun habe ich festgestellt, dass ab dem Zeitpunkt, wenn die 1. Schleife beendet ist in der zweiten keine Bilder mehr aus dem Queue geholt. D.h. es wurden insgesamt 500 Bilder in den Queue geschrieben, es werden aber nur ca. 200 Bilder in der zweiten Schleife ausgelesen. Die zweite Schleife läuft zwar auch noch die restlichen 300 Iterationen durch, holt aber keine Bilder mehr aus dem Queue. Testweise habe ich noch neben den Bildern auch noch Zufallszahlen in den Queue geschrieben, welche auch problemlos bis zum Ende ausgelesen werden.

Kurz: Für Zahlen, Boolsche Werte usw. funktioniert die Übertragung mit Queues einwandfrei. Nur mit Bildern nicht. Kann das sein?
Hat jemand eine Erklärung dafür? Oder noch besser: Eine Lösung!

schöne Grüße

labrat
Hallo Labrat,

bei Images ist es so, dass du nicht die Bilddaten sondern eine Referenz auf die Bilddaten in die Queue schreibst. Daher gehen die Daten der Bilder verloren. Eine mögliche Abstellmaßnahme wäre, dass du in deiner For-Schleife aus dem Bild ein Array machst und tatsächlich die Daten des Bildes in die Queue reinfeuerst.

Bei Images wird nicht wie bei LabVIEW üblich ein Call by Reference ausgeführt und kein Call by Value.

MfG Carsten
Referenz-URLs