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!
ich habe versucht ein Erzeuger Verbraucher System zu erstellen.
Die obere Schleife im Bild ist der Erzeuger.
Die untere Schleife im Bild der Verbraucher.
Um die CPU ein wenig zu entlasten, lasse ich die Verbraucher Schleife immer mindestens 100ms warten.
Nachdem ich die VI nun starte kommt nach einigen Sekunden die Meldung: "Nicht genügend Speicher zum Abschließen der Operation".
Wenn ich den Dialog durch ein Klick auf den Ok Button schließe, läuft das Programm ohne weitere Probleme weiter.
1) Warum sagt er mir "Nicht genügend Speicher zum Abschließen der Operation"?
Es sind doch grad mal 1.1 GB Arbeitsspeicher belegt. Das heißt 0.9 GB sind noch frei.
(Habe einen 2 GB Arbeitsspeicher und einen Intel Core 2 Duo Prozessor)
2) Ich hole die Daten alle 100 ms aus dem Puffer in der Verbraucher Schleife. Die Erzeuger Schleife
erstellt die Daten aber wesentlich schneller, da ich dort kein Wait verwende. So wie ich das verstehe
wird alle 100ms Sekunden ein einziger Wert aus dem Puffer geholt und das Diagramm gezeichnet.
Der Puffer müsste mir doch total schnell vollaufen, so dass vom Erzeuger neu erzeugte Werte erst gar nicht in den Puffer
hineingelegt werden können. Das heißt ich müsste Werte verlieren. Seh ich das richtig?
3) Werden die in den Puffer gelegten Werte im Arbeitsspeicher oder auf der Festplatte abegelgt? Oder sogar ganz woanders?
Developer Suite Core -> LabVIEW 2015 Prof.
2006
EN
71083
Deutschland
RE: Erzeuger/Verbraucher
Lad' mal Dein VI hoch. Wo sind die 100 ms?
Gruß Markus
-------------------------------------------------------------------------- Bitte stellt mir keine Fragen über PM, dafür ist das Forum da - andere haben vielleicht auch Interesse an der Antwort !!
--------------------------------------------------------------------------
Developer Suite Core -> LabVIEW 2015 Prof.
2006
EN
71083
Deutschland
RE: Erzeuger/Verbraucher
Du füllst Dir die Queue so schnell es die CPU hergibt. Mach' doch mal in der oberen Schleife auch eine Verzögerung rein.
Gruß Markus
EDIT: Dann ist auch die 50 % - Auslastung weg (ein Kern ist bei Dir gerade zu 100 % ausgelastet!).
-------------------------------------------------------------------------- Bitte stellt mir keine Fragen über PM, dafür ist das Forum da - andere haben vielleicht auch Interesse an der Antwort !!
--------------------------------------------------------------------------
In die obere Schleife möchte ich kein Wait reinmachen.
Im eigentlichen Programm welches sehr komplex ist, gibt es keine Erzeuger Verbraucher Struktur.
Dort gibt es eine riesige While Schleife. Irgendwo dort wird dann ein Wert von der Messkarte gelesen
und an einen Regler weitergegeben. Der Regler benötigt spätestens nach 20ms einen neuen Wert,
ansonsten wir die Prüfmaschine falsch geregelt. Die Prüfmaschine erzeugt nämlich alle 20ms einen neuen
Wert.
In dem komplexen Code wird kein Wait o.ä. verwendet. Bei dem Rechner dort handelt es sich um einen
Windows XP Rechner mit nur einem Prozessor der nur einen Kern hat.
Wenn kein Diagramm gezeichnet wird, dann funktioniert das Programm gut und der Regler regelt die Prüfmaschine richtig.
Wird aber ein Diagramm gezeichnet so gehen Werte irgendwo verloren und die Maschine regelt falsch.
Vermutlich nimmt das Zeichnen des Diagramms mehr als 20ms in Anspruch, so dass der Regler einen Wert verpasst.
Daher wollte ich versuchen ein Erzeuger Verbraucher System zu erstellen.
Im Erzeuger System werden die Werte aus der Messkarte gelesen und der Regler erhält den akutellen Wert.
Ich kann kein Wait da reinsetzen, da der Regler ununterbrochen arbeiten muss.
Die Zeichnung des Diagramms kann ruhig eine halbe Sekunde oder vielleicht auch ne Sekunde verzögert erfolgen.
Darum verwende ich in der sehr stark vereinfachten Version, die ich hier hochgeladen habe im Erzeuger
kein Wait und im Verbraucher ein Wait. Das Wait im Verbraucher soll dafür sorgen, dass der Regler der noch
in die Erzeuger Schleife kommt fast die gesamte Aufmerksamkeit der CPU erhält.
Ist das ein falscher Ansatz den ich mit der Erzeuger Verbraucher Schleife grad wähle um das Problem zu lösen?
Developer Suite Core -> LabVIEW 2015 Prof.
2006
EN
71083
Deutschland
RE: Erzeuger/Verbraucher
Wenn Du so schnell regeln willst, dann würde ich mich nach einem Realtime-System umschauen (cRIO,...), weil ungebremste Whileschleifen sind (meistens) Mist.
Gruß Markus
-------------------------------------------------------------------------- Bitte stellt mir keine Fragen über PM, dafür ist das Forum da - andere haben vielleicht auch Interesse an der Antwort !!
--------------------------------------------------------------------------
04.12.2012, 09:56 (Dieser Beitrag wurde zuletzt bearbeitet: 04.12.2012 10:02 von Lucki.)
In die untere Schelife gehört normalerweise kein Wait rein. Die Queue-Funktion "Element entfernen" wartet so lange, bis wieder etwas in der Queue ist, und synchronisiert sich damit von selbst mit der anderen Schleife. Eine CPU-Überlastung ist da auch nicht zu befürchten, solange die Erzeugung in der oberen Schleife nicht mit unendlich hoher Rate geschieht.
Ein andere Möglichkeit der Synchronisation ist die von der Erzeugerseite her. Wenn die Queue voll ist, wartet nämlich die Funktion "Element einfügen" so lange, bis wieder Platz in der Queue ist. (Bei unbegrenzter Queue-Länge kommt es statt dessen, wie hier passiert, zum Memory-Fehler)
Also Du hast zwei Möglichkeiten:
a) Wait in die obere Schleife (Wait entfällt, wenn der Erzeugerprozess von sich aus Zeit beansprucht)
b) Wait in der unteren Schleife lassen, aber die Queue-Länge von unbegrenzt auf einen sinnvollen Wert ändern.
Bei Variante b) ist zu beachten, daß die Verarbeitung in der Verbraucherschleife nicht aktuell ist. Die Schlange ist immer voll, und das älteste Element, welches womöglich lange Zeit vorher erzeugt wurde, wird vom Verbraucher verarbeitet.
04.12.2012, 11:00 (Dieser Beitrag wurde zuletzt bearbeitet: 04.12.2012 11:02 von Y-P.)
Developer Suite Core -> LabVIEW 2015 Prof.
2006
EN
71083
Deutschland
RE: Erzeuger/Verbraucher
Hast Du bei seinem Bsp. mal im Taskmanager unter "Leistung" geschaut (50 Prozent für so ein Progrämmchen sind mMn nicht normal)?
Gruß Markus
(04.12.2012 09:56 )Lucki schrieb: Eine CPU-Überlastung ist da auch nicht zu befürchten, solange die Erzeugung in der oberen Schleife nicht mit unendlich hoher Rate geschieht.
-------------------------------------------------------------------------- Bitte stellt mir keine Fragen über PM, dafür ist das Forum da - andere haben vielleicht auch Interesse an der Antwort !!
--------------------------------------------------------------------------
04.12.2012, 19:03 (Dieser Beitrag wurde zuletzt bearbeitet: 04.12.2012 19:04 von Lucki.)
(04.12.2012 11:00 )Y-P schrieb: Hast Du bei seinem Bsp. mal im Taskmanager unter "Leistung" geschaut (50 Prozent für so ein Progrämmchen sind mMn nicht normal)?
In seinem Beispiel hält die Überlastung so lange an, bis alles Memory verbraucht ist und des Prog mit Fehlermeldung abbricht.
Wenn aber die Queue-Größe begrenzt würde, hätte man die "Überlastung" nur bis die Queue voll ist. Ab da würde sich die Erzeugerschleife dem 100ms-Takt der Verbraucherscheife anpassen, und eine Fehlermeldung kommt nicht. (Praktisch sinnvoll muss das Ganze aber deswegen immer noch nicht sein)
so habe grad nochmal versucht ein Erzeuger Verbraucher System zu erstellen.
Die obere Schleife ist wieder der Erzeuger. Sie erzeugt alle 50ms Daten.
Diesmal kommen die Daten von der Laufvariablen i der Schleife.
Diese Daten lege ich in die Queue rein.
Die untere Schleife ist der Verbraucher. Sie entimmt alle 5000 ms Daten
aus der Queue und zeichnet sie in ein Diagramm.
Die Queue hat eine Beschränkung von 10 Elementen.
Ich kann mir die 10 Elemente die im Puffer sind im Array auf dem Frontpanel anschauen.
Mich wundert es, dass keine Daten verloren gehen. Es wird eine saubere gerade
Linie im Diagramm gezeichnet. Das versteh ich aber nicht.
Die Erzeugerschleife wird alle 50ms ausgeführt. Dabei versucht sie bei jeder Ausführung
einen neuen Wert in den Puffer zu legen. Wenn bereits 10 Werte drinne sind, und das
dürfte nach 500 ms der Fall sein, dann wird die Erzeugerschleife zwar weiterhin alle 50ms
ausgeführt, aber sie legt keine neuen Daten mehr in den Puffer, da dieser voll ist.
Nach 500 ms müssten die Werte {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} drin sein.
Wenn nun die Verbraucherschleife nach 5000ms den ersten Wert herausholt, dann
könnte die Erzeugerschleife im nächsten Schleifendurchlauf einen neuen Wert
in den Puffer legen. Die Laufvariable müsste zu diesem Zeitpunkt ungefähr den Wert 100 haben.
Somit müsten in den Puffer dieser Wert hineingelegt werden.
Also müsste die Queue nun so aussehen {2, 3, 4, 5, 6, 7, 8, 9, 10, 100}
Das bedeutet das im Diagramm irgendwann ein plötzlicher Sprung vom Wert 10 auf den Wert 100 zu sehen sein sollte.
Dem ist aber nicht so. Warum? Wo liegt mein Denkfehler?