INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.


Antwort schreiben 

Design "Erzeuger/Verbraucher



Wenn dein Problem oder deine Frage geklärt worden ist, markiere den Beitrag als "Lösung",
indem du auf den "Lösung" Button rechts unter dem entsprechenden Beitrag klickst. Vielen Dank!

05.10.2009, 17:00
Beitrag #1

wernerIBN Offline
Datenflussumgeher
**


Beiträge: 124
Registriert seit: Sep 2009

8.6 und 2011
2000
DE

52425
Deutschland
Design "Erzeuger/Verbraucher
Hallo,
ich habe noch eine Frage zum Design "Erzeuger/Verbraucher:

Ich verwende Erzeuger-Verbraucher um das Erzeugen der Ereignisse von der Verarbeitung zu trennen.
So wie ich das sehe, werden die Ereignisse ja in eine Queue gestellt, aus der sich dann die Verbraucherschleife bedient.

Also Beispiel: ein Button "Hallo" wird gedrückt, die Erzeugerschleife stellt den String Hallo in die Queue.

Dort holt die Verbraucherschleife den String Hallo raus, und verarbeitet den.

Ich stelle nun fest, dass wenn diese Verarbeitung z.B. 10 sekunden dauert, das ganze GUI 10 Sekunden blockiert ist.

Ich verstehe nicht, wieso der Button „Hallo“ (andere Buttons genauso…) gedrückt bleibt, bis der Code der Verbraucher-Case durch ist.

Ich hätte eigentlich gedacht, der Button macht einen event, der wird in der Erzeuger-Schleife in die Queue eingereiht, und fertig ist. Aber der Button bleibt unten, bis die betreffende Verbraucher-Queue abgearbeitet ist. Also nicht asynchron, nicht parallel.

Die GUI bleibt blockiert. Das gefällt mir nicht…Dry

Kann man das so abändern, dass die GUI immer funktioniert, und die Erzeugerschleife und die Verbraucherschleife parallel ausgeführt werden ?

Noch lieber hätte ich, wenn praktisch jeder case meiner Verbraucherschleife parallel läuft, quasi in einem eigenen Thread, Tongue aber ich will ja nicht zu extrem werden.

Ich verwende LV8.6, XP und habe 4 Cores.

Werner

Erfahrung ist die Summe der gemachten Fehler
KISS - Keep it simple and stupid
Walking on water and developing software from a specification are easy if both are frozen. – Edward V Berard
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
05.10.2009, 18:40
Beitrag #2

IchSelbst Offline
LVF-Guru
*****


Beiträge: 3.687
Registriert seit: Feb 2005

11, 14, 15, 17, 18
-
DE

97437
Deutschland
Design "Erzeuger/Verbraucher
' schrieb:Also Beispiel: ein Button "Hallo" wird gedrückt, die Erzeugerschleife stellt den String Hallo in die Queue.
Dort holt die Verbraucherschleife den String Hallo raus, und verarbeitet den.
So geht das.

Zitat:Ich stelle nun fest, dass wenn diese Verarbeitung z.B. 10 sekunden dauert, das ganze GUI 10 Sekunden blockiert ist.
Dann hast du was falsch programmiert.

Zitat:Kann man das so abändern, dass die GUI immer funktioniert, und die Erzeugerschleife und die Verbraucherschleife parallel ausgeführt werden ?
Klar, du must dein Programm nur richtig machen. Wink


Zeig mal ein (Muster-)VI, das den Fehler zeigt.

Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
06.10.2009, 07:40
Beitrag #3

abrissbirne Offline
LVF-Stammgast
***


Beiträge: 480
Registriert seit: Aug 2007

LV2009, LV2010
2007
EN

66123
Deutschland
Design "Erzeuger/Verbraucher
' schrieb:Hallo,
ich habe noch eine Frage zum Design "Erzeuger/Verbraucher:

Ich verwende Erzeuger-Verbraucher um das Erzeugen der Ereignisse von der Verarbeitung zu trennen.
So wie ich das sehe, werden die Ereignisse ja in eine Queue gestellt, aus der sich dann die Verbraucherschleife bedient.

Also Beispiel: ein Button "Hallo" wird gedrückt, die Erzeugerschleife stellt den String Hallo in die Queue.

Dort holt die Verbraucherschleife den String Hallo raus, und verarbeitet den.
Korrekt. So sollte es sein.

' schrieb:Ich stelle nun fest, dass wenn diese Verarbeitung z.B. 10 sekunden dauert, das ganze GUI 10 Sekunden blockiert ist.

Ich verstehe nicht, wieso der Button „Hallo“ (andere Buttons genauso…) gedrückt bleibt, bis der Code der Verbraucher-Case durch ist.

Ich hätte eigentlich gedacht, der Button macht einen event, der wird in der Erzeuger-Schleife in die Queue eingereiht, und fertig ist. Aber der Button bleibt unten, bis die betreffende Verbraucher-Queue abgearbeitet ist. Also nicht asynchron, nicht parallel.

Die GUI bleibt blockiert. Das gefällt mir nicht…Dry
Das kann ich mir vorstellen. Wie IchSelbst bereits gesagt hat, hast du wohl etwas falsch gemacht.

' schrieb:Kann man das so abändern, dass die GUI immer funktioniert, und die Erzeugerschleife und die Verbraucherschleife parallel ausgeführt werden ?
Ja.

' schrieb:Noch lieber hätte ich, wenn praktisch jeder case meiner Verbraucherschleife parallel läuft, quasi in einem eigenen Thread, Tongue aber ich will ja nicht zu extrem werden.
Wie soll denn jeder Case parallel abgearbeitet werden? Du kannst mehrere parallele Schleifen ausführen. Standartmäßig habe ich mindestens drei Schleifen. Eine Producer, eine Consumer und eine die mein Frontpanel updated. Letztere ist wiederum von der Consumer-Schleife abhängig. Mit dieser Architektur kannst du meiner Meinung nach 80-90% deiner Aufgabenstellungen erledigen. Du kannst allerings auch noch mehr parallele Schleifen hinzufügen. Da sind dir deiner Fantasie keine Grenzen gesetzt.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
06.10.2009, 08:00
Beitrag #4

IchSelbst Offline
LVF-Guru
*****


Beiträge: 3.687
Registriert seit: Feb 2005

11, 14, 15, 17, 18
-
DE

97437
Deutschland
Design "Erzeuger/Verbraucher
' schrieb:Ich stelle nun fest, dass wenn diese Verarbeitung z.B. 10 sekunden dauert, das ganze GUI 10 Sekunden blockiert ist.
Die Oberfläche wäre z.B. dann für die Dauer des Eventcases blockiert, wenn im Eventcase "Frontpanale sperren" angekäckelt ist. Oder wenn das Resetten des Tasters an der falschen Stelle gemacht wird.

Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
06.10.2009, 11:24
Beitrag #5

wernerIBN Offline
Datenflussumgeher
**


Beiträge: 124
Registriert seit: Sep 2009

8.6 und 2011
2000
DE

52425
Deutschland
Design "Erzeuger/Verbraucher
Hi danke für die guten Anregungen.
Ich arbeite noch damit, dauert noch was, da ichs noch nicht ganz verstanden habe.

Ausserdem versteh ich nicht, wie das hier mit dem zitieren geht... sorry...

Zitat: Die Oberfläche wäre z.B. dann für die Dauer des Eventcases blockiert, wenn im Eventcase "Frontpanale sperren" angekäckelt ist. Oder wenn das Resetten des Tasters an der falschen Stelle gemacht wird.

Also:
Ich vermute, du hast recht.
Ich verwende den OK-Button so wie du vermutest.

Bei Ereignisse bearbeiten steht auch extra:
Hinweis: Bei der Verarbeitung einer Wertänderung (genau das hab ich gewählt) an einem gelatschten boolschen Element wird nicht automatisch der vorgesehene Schaltvorgang ausgeführt. Um das Element ordnungsgemäß in den Ausgangszustand zurückzusetzen, muss das Element erst ausgelesen werden.

Nur: ich lese den Button doch oben in der Erzeugerschleife aus, zumindest hab ich das Ding da reingezogen. Ich versteh nicht, wieso das Mistding gedrückt bleibt, auch wenn der text in die Queue gestellt wurde.
In meiner Verbraucherschleife ist der Button gar nicht drinn, trotzdem kommt der hoch, wenn die Verbraucherschleife diesen Case abgearbeitet hat. Wie funktioniert das ? Ich verstehs nicht.

Oben im Ereignis-Case habe ich die Checkbox

[x]Frontpanel sperren, bis der Code für dieses Ereignis abgearbeitet wurde

Extra deaktiviert, trotzdem kann ich an der GUI nix bedienen bis der Case fertig ist.
Komisch.

Zitat: Wie soll denn jeder Case parallel abgearbeitet werden? Du kannst mehrere parallele Schleifen ausführen. Standartmäßig habe ich mindestens drei Schleifen. Eine Producer, eine Consumer und eine die mein Frontpanel updated. Letztere ist wiederum von der Consumer-Schleife abhängig. Mit dieser Architektur kannst du meiner Meinung nach 80-90% deiner Aufgabenstellungen erledigen. Du kannst allerings auch noch mehr parallele Schleifen hinzufügen. Da sind dir deiner Fantasie keine Grenzen gesetzt.

Danke für die Anregung. Also deine Producer, deine Consumer und deine Frontpanelschleife arbeitet dann wirklich parallel ? Die Queue zwischen Consumer und Producer hindert nicht die parallele Ausführung ?

Deine Frontpanelschleife ist eine einfache While mit Timer drinn, die etwa sekündlich oder so abläuft ?

Ich möchte das VI so bedienen, wie ein Messgerät. Im Hintergrund läuft die Messung, Anzeigen werden aktualisiert und ich kann die GUI bedienen. Genau das scheint ja mit deinem Konzept zu gehen. Richtig ?

Werner

Erfahrung ist die Summe der gemachten Fehler
KISS - Keep it simple and stupid
Walking on water and developing software from a specification are easy if both are frozen. – Edward V Berard
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
06.10.2009, 11:41
Beitrag #6

jg Offline
CLA & CLED
LVF-Team

Beiträge: 15.864
Registriert seit: Jun 2005

20xx / 8.x
1999
EN

Franken...
Deutschland
Design "Erzeuger/Verbraucher
' schrieb:Also:
Ich vermute, du hast recht.
Ich verwende den OK-Button so wie du vermutest.

Bei Ereignisse bearbeiten steht auch extra:
Hinweis: Bei der Verarbeitung einer Wertänderung (genau das hab ich gewählt) an einem gelatschten boolschen Element wird nicht automatisch der vorgesehene Schaltvorgang ausgeführt. Um das Element ordnungsgemäß in den Ausgangszustand zurückzusetzen, muss das Element erst ausgelesen werden.
Eine Latch-Button platziere ich IMMER in den Value-Change-Case der Event-Struktur des Buttons! Damit wird er in diesem Case ausgelesen und zurückgesetzt.

Offtopic2
Zum Thema zitieren:
Erst den Zitieren Button unterhalb des Beitrages bzw. der Beiträge (ja, geht auch für mehrere), den/die du zitieren willst, anklicken,
   
dann Antwort schreiben.

Oder nachträglich in "quote" Tags setzen - Text markieren, dann Button drücken:
   

Gruß, Jens

Wer die erhabene Weisheit der Mathematik tadelt, nährt sich von Verwirrung. (Leonardo da Vinci)

!! BITTE !! stellt mir keine Fragen über PM, dafür ist das Forum da - andere haben vielleicht auch Interesse an der Antwort!

Einführende Links zu LabVIEW, s. GerdWs Signatur.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
Anzeige
06.10.2009, 12:22
Beitrag #7

IchSelbst Offline
LVF-Guru
*****


Beiträge: 3.687
Registriert seit: Feb 2005

11, 14, 15, 17, 18
-
DE

97437
Deutschland
Design "Erzeuger/Verbraucher
' schrieb:Nur: ich lese den Button doch oben in der Erzeugerschleife aus, zumindest hab ich das Ding da reingezogen. Ich versteh nicht, wieso das Mistding gedrückt bleibt, auch wenn der text in die Queue gestellt wurde.
Oh, da gibt es schon noch Möglichkeiten. Das Auslesen des Elementes, in dessen Folge zuerst mal lediglich der Wert des Elementes zurückgesetzt wird, erzwingt zwar einen Refresh am Bildschirm - der kann aber zeitversetzt (zwischen 1ms und 10 Sekunden sag ich jetzt mal) passieren.

Wenn die gesamte GUI (also dein FP) blockiert ist, kann das auch daran liegen, dass irgendwo eine While-Schleife (z.B. die vom Verbraucher) soviel Prozessor-Leistung für das Blockdiagramm verbraucht, dass keine Zeit mehr für den FP-Refreh bleibt. Manchmal hilf da eine Wartezeit von 1ms in die While-Schleife zu plazieren.

Gut wäre es, wenn du ein MusterVI mit den Auffälligkeiten erstellen kannst.

Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
06.10.2009, 16:57
Beitrag #8

wernerIBN Offline
Datenflussumgeher
**


Beiträge: 124
Registriert seit: Sep 2009

8.6 und 2011
2000
DE

52425
Deutschland
Design "Erzeuger/Verbraucher
' schrieb:Offtopic2
Zum Thema zitieren:
Erst den Zitieren Button unterhalb des Beitrages bzw. der Beiträge (ja, geht auch für mehrere), den/die du zitieren willst, anklicken,
[attachment=49706:Image01.png]
dann Antwort schreiben.

Oder nachträglich in "quote" Tags setzen - Text markieren, dann Button drücken:
[attachment=49707:Image02.png]

Gruß, Jens

Jens,
danke für die Hilfe beim zitieren... ist ja praktisch... wenn mans erst mal verstanden hatHmm

Werner

Erfahrung ist die Summe der gemachten Fehler
KISS - Keep it simple and stupid
Walking on water and developing software from a specification are easy if both are frozen. – Edward V Berard
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
06.10.2009, 17:28
Beitrag #9

wernerIBN Offline
Datenflussumgeher
**


Beiträge: 124
Registriert seit: Sep 2009

8.6 und 2011
2000
DE

52425
Deutschland
Design "Erzeuger/Verbraucher
' schrieb:Oh, da gibt es schon noch Möglichkeiten. Das Auslesen des Elementes, in dessen Folge zuerst mal lediglich der Wert des Elementes zurückgesetzt wird, erzwingt zwar einen Refresh am Bildschirm - der kann aber zeitversetzt (zwischen 1ms und 10 Sekunden sag ich jetzt mal) passieren.

Wenn die gesamte GUI (also dein FP) blockiert ist, kann das auch daran liegen, dass irgendwo eine While-Schleife (z.B. die vom Verbraucher) soviel Prozessor-Leistung für das Blockdiagramm verbraucht, dass keine Zeit mehr für den FP-Refreh bleibt. Manchmal hilf da eine Wartezeit von 1ms in die While-Schleife zu plazieren.

Gut wäre es, wenn du ein MusterVI mit den Auffälligkeiten erstellen kannst.

Hi,
ich antworte so spät, weil ich langsam begreife wo es hängt.
Meine Erzeugerschleife reagiert auf Drücken von Buttons meines Frontpanels, und stellt dann passende Strings in die Queue.
Meine Verbraucherschleife holt sich diese Strings raus, und bearbeitet sie im passenden case.
Auch wenn ich in so einem Case einen LabVIEW-Timer mit einer Wartezeit von 10000ms stelle, funktioniert die GUI korrekt.

Ich habe aber eine DLL in C (VS2005) erstellt, die ich im betreffenden case aufrufe. Diese DLL kommuniziert über TCP/IP mit einem SerialDeviceServer, der im Prinzip eine RS232 Schnittstelle bereitstellt. Daran hängen RS232-Geräte (mehrere). Die Kommunikation funktioniert so, dass so ein Gerät ein Kommando gesendet bekommt (z.B.: "VALVE7 OPEN") und dann antwortet (z.B: "OK"). Diese Antwort erfolgt zeitverzögert, z.B.: nach 10 Sekunden.

Was bei mir vermutlich der Fall ist, ist dass LV in meine DLL springt (CallLibraryFunctionNode) und da halt etwa 10 Sekunden hängt. Im C-Code hänge ich in den 10 Sekunden in einer while-Schleife, wo ich mit sleep(100); halt warte, und dachte so CPU-Zeit abzugeben. Aber offensichtlich blockiere ich so das gesamte LabVIEW, so dass weder meine GUI-Buttons sich bewegen, noch sonst was ausgeführt wird.

Hier ein C-Code-Fragment von mir:

[code]//unterscheiden zwischen UDP und TCP

Erfahrung ist die Summe der gemachten Fehler
KISS - Keep it simple and stupid
Walking on water and developing software from a specification are easy if both are frozen. – Edward V Berard
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
06.10.2009, 18:10
Beitrag #10

IchSelbst Offline
LVF-Guru
*****


Beiträge: 3.687
Registriert seit: Feb 2005

11, 14, 15, 17, 18
-
DE

97437
Deutschland
Design "Erzeuger/Verbraucher
' schrieb:Diese DLL kommuniziert über TCP/IP mit einem SerialDeviceServer,
Über TCP/IP? Da, so befürchte ich, kann es zu einem Hängen des gesamten Prozesses kommen. Der gesamte Prozess wäre wie DLL und LV.

Zitat:wo ich mit sleep(100); halt warte, und dachte so CPU-Zeit abzugeben.
Die Sache mit CPU-Zeit abgeben stimmt schon so. Aber: Während dieser 100ms steht der gesamte Prozess, der sleep() aufruft - also die DLL und das LV-Programm !

Zitat:Hier ein C-Code-Fragment von mir:
muss ich mir noch ankucken.


Zitat:Ist das mein Fehler ?
Aus Erfahrung würde ich auf zwei Sachen tippen.
Sleep(): Sleep() stoppt den gesamten Prozess.
TCP/IP: Wenn der TCP/P-Socket nicht event-getriggert arbeitet, könnte es schon sein, dass die TCP/IP-Unterprogramme erst beendet werden, wenn daten ankommen, oder wenn ein Timeout eintritt.

Zitat:KannLv86_imgüberhaupt weiterlaufen, während ein VI in einer externen DLL steckt
Hier würde ich sagen: Das sollte gehen.
Das SubVI, welches die DLL aufruft, müsste in einer eigenen Task (= While-Schleife) laufen.

Zitat:und dort in einer Schleife mit sleep() verweilt ?
Probier's mal aus: SubVI mit DLL auf eigener While-Schleife. Möglicherweise managert LV diese parallele While-Schleife so, dass der Effekt, der mit mit Sleep() bekannt ist, eleminiert wird. Ein Versuch wäre es Wert.

Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
30
Antwort schreiben 


Möglicherweise verwandte Themen...
Themen Verfasser Antworten Views Letzter Beitrag
  Ansprechendes Design des Frontpanels | Muster in Hintergrund einfügen dulfried 3 3.738 23.08.2017 17:45
Letzter Beitrag: GerdW
  Error Handling in einem Queue Message Design Architektur galilio 2 4.086 09.08.2016 12:20
Letzter Beitrag: galilio
  Protokolieren durch TDMS in einer Erzeuger und Verbraucher Synchronisation Atlaspremier 0 2.396 28.07.2016 13:21
Letzter Beitrag: Atlaspremier
  Queued Message Handler Design galilio 3 5.430 14.07.2016 15:34
Letzter Beitrag: Freddy
  Design Pattern für sequentiellen Verlauf galilio 6 4.267 23.02.2016 08:50
Letzter Beitrag: Freddy
  Erzeuger-Verbraucher Muster Abbruch Verbraucherschleife mit Abarbeitung der Queue lumaxo 5 6.019 12.02.2015 13:55
Letzter Beitrag: Lucki

Gehe zu: