LabVIEWForum.de - Debug von irregulären LV-Zuständen

LabVIEWForum.de

Normale Version: Debug von irregulären LV-Zuständen
Du siehst gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
Seiten: 1 2
' schrieb:Pardon, wo soll der Vorteil liegen? Solch ein VI zu bauen macht einen Haufen Arbeit. Ich sehe auch unter extremen Voraussetzungen wie gleichzeitiger lese- und Schreibzugriff nur die Möglichkeit das Unsinn gelesen wird.... aber irreguläres Verhalten, blue-Screen....

Gottfried
Den Vorteil hat Freedive erklärt: Du kannst noch einen Errorcluster integrieren, dann hierüber wieder den Datenfluss innerhalb von LabVIEW deterministisch vorgeben und somit die Gefahr von Race Conditions stark verringern.

Globale Variablen sollte man aus IMHO nur unter folgenden Einschränkungen verwenden:
1. Einfache Datentyp (also z.B. keine großen Arrays)
2. Es wird diese Globale Variable nur an einer (oder sehr wenigen) Stelle im Programm gesetzt und dann nur noch lesend verwendet.

MfG, Jens
' schrieb:aber irreguläres Verhalten, blue-Screen....
Ich hätte es nicht geschrieben, wenn ich es nicht erlebt hätte.

Ursache war ein 2D-Array als globale Variable, die in zwei While-Schleifen jeweils lesend und schreibend manipuliert wurde. Warum? War halt sehr einfach und ohne einen Haufen Arbeit zu realisieren. Selbst bei dauernder Abarbeitung beider Schleifen (24 Stunden, 7 Tage ...) ist das Problem nur alle drei Wochen mal aufgetreten. Und warum war da ein BlueScreen? Genau in der halben µs, in der in der einen Schleife auf das Feld zugegriffen wurde, hat LV einen Threadwechsel gemacht und im anderen Thread mal kurzerhand der Speicher neu alloziert. Dann hab ich mir das mal durch den Kopf gehen lassen, alles mit Flags "threadsicher" gemacht - und plötzlich war der Fehler weg?

Und da jetzt alles in SubVIs liegt und das selbe SubVI nicht gleichzeitig ausgeführt wird (jaja, außer invarianter Ablauf), sind alle Probleme behoben. Der Haufen Arbeit lohnt sich immer. Weil der nämlich nie größer ist, als die Arbeit hinterher.
dieses phen kenne ich nur bei hyperthreading enabled und lv version < 8.5
' schrieb:Ich hätte es nicht geschrieben, wenn ich es nicht erlebt hätte.

Ursache war ein 2D-Array als globale Variable, die in zwei While-Schleifen jeweils lesend und schreibend manipuliert wurde. Warum? War halt sehr einfach und ohne einen Haufen Arbeit zu realisieren. Selbst bei dauernder Abarbeitung beider Schleifen (24 Stunden, 7 Tage ...) ist das Problem nur alle drei Wochen mal aufgetreten. Und warum war da ein BlueScreen? Genau in der halben µs, in der in der einen Schleife auf das Feld zugegriffen wurde, hat LV einen Threadwechsel gemacht und im anderen Thread mal kurzerhand der Speicher neu alloziert. Dann hab ich mir das mal durch den Kopf gehen lassen, alles mit Flags "threadsicher" gemacht - und plötzlich war der Fehler weg?

Und da jetzt alles in SubVIs liegt und das selbe SubVI nicht gleichzeitig ausgeführt wird (jaja, außer invarianter Ablauf), sind alle Probleme behoben. Der Haufen Arbeit lohnt sich immer. Weil der nämlich nie größer ist, als die Arbeit hinterher.

Wieder was gelernt

Danke

Gottfried
' schrieb:Pardon, wo soll der Vorteil liegen? Solch ein VI zu bauen macht einen Haufen Arbeit. Ich sehe auch unter extremen Voraussetzungen wie gleichzeitiger lese- und Schreibzugriff nur die Möglichkeit das Unsinn gelesen wird.... aber irreguläres Verhalten, blue-Screen....

Gottfried

Es ist Arbeit und solange Du nur eine FGV schreibst die einfach eine get und put methode hat auch noch nicht mal so viel besser als eine Global (obwohl da schon ein paar kleine Vorteile sind). Wirklich interessant wirds erst wenn Du aus dieser FGV eine IGV (intelligente globale Variable) machst. Um es mal an einem einfachen Beispiel sehen zu lassen:

Nimm an Du hast irgendwo einen Zähler den Du manchmal inkrementieren und manchmal dekrementieren musst und dann möchte man ihn natürlich noch lesen können. Das kannst Du tun indem Du irgendwo eine dumme Global hinsetzt und jedesmal wenn Du die verändern musst liest Du sie machst die Änderung und schreibst sie zurück. Und dann staunst Du dass das ja überhaupt nie stimmt. Denn an Stelle A liest Du den Wert, Stelle B liest in auch. Bei A wird er inkrementiert und zurückgeschriben und B dekrementiert ihn und schreibt ihn dann zurück. Grundsätzlich kann das Resultat dieses Programmes nun dreifach sein. Die Globale kann wieder dasselbe Resultat haben als zuvor (das ist ziemlich sicher was Du eigentlich willst). Oder sie kann eins grösser oder kleiner sein dann zuvor (ziemlich sicher nicht was Du willst). Das ist eine Race Condition.

Das Ganze in einer IGV mit init, get, increment, und decrement Methode GARANTIERT Dir dass der Wert am Ende wieder gleich ist als zuvor da die IGV als SubVI nicht nur halb von Stelle A ausgeführt werden kann bevor B sie startedt, und ist effizienter da zum inkrementieren und dekrementieren nicht jeweils der Inhalt einer Global herauskopiert und wieder zurückgekopiert werden muss. Ok für einen Counterwert macht dieser Effizienzgewinn nicht wirklich was aus aber mach daraus ein Array von 10000 Messwerten und der Unterschied zwischen Global und IGV ist schon deutlich messbar und wenn es gar um 1000000 Messwerte geht ist es der Unterschied der im einen Fall eine untoleriebar langsame Applikation von einer flott daher laufenden Applikation unterscheidet.

Im Prinzip ist eine IGV schon eine Art Objekt die die Operationen auf bestimmte Daten kapselt und Dir ein Interface zur Manipulation dieser Daten gibt. Ja es ist etwas Arbeit so etwas zu schreiben aber wenn Du mal damit begonnen bist wirst Du die Vorteile davon schnell einsehen und es nicht mehr mit Globals tun wollen.

Rolf Kalbermatter
Seiten: 1 2
Referenz-URLs