LabView Fan Group
aplikuj!

Najbliższe spotkanie: 20.11.2017

Godzina 18:00, sala 107 bud E-1 Do zobaczenia!

Wszystko co chciałeś wiedzieć o FGV, ale bałeś się zapytać

Maciej Jakubów

Zmienna globalna posiada właściwości pozwalające na przekazywanie danych pomiędzy poszczególnymi subvi. To co stanowi jej piękno sprowadza na programistę szereg zagrożeń. Przede wszystkim niezwykle trudno przewidzieć zachowanie takiej zmiennej z uwagi na jednoczesność dostępu do zmiennej z wielu podprogramów. Rozwiązaniem które częściowo może pomóc jest właśnie globalna zmienna funkcjonalna.

Co to jest Functional Global Variable (FGV) ?

Historia zmiennej sięga zamierzchłych czasów LabView 2 kiedy to grupa programistów ustaliła że niezainicjowany rejestr przesuwny przyjmie swoja poprzednią wartość. Dobrze że tak się stało ponieważ rozważano alternatywne rozwiązanie - przyjmowanie stanu domyślnego dla typu danych dla jakich rejestr został przygotowany. 

Pierwotnie FGV było również protezą ponieważ przed wprowadzeniem LabView 3 nie istniał typ zmiennej globalnej. Pomimo wprowadzenia zmiennych globalnych używamy FGV po dziś dzień.

Z czego składa się FGV ?

Podstawowym składnikiem potrzebnym do sporządzenia globalnej zmiennej funkcjonalnej jest niezainicjowany rejestr przesuwny. Pozostałe elementy wymuszone są poprzez składnie języka LabView oraz to co chcielibyśmy by nasza zmienna robiła z danymi w niej zawartymi. Poniżej na rysunku 1 przedstawiono schematycznie taką zmienną. 

Rysunek 1. Podstawowe składniki FGV

Taka zmienna pozwala nam na zapis i odczyt danych.  Stosunkowo proste użycie dostępnych narzędzi niestety nie zabezpiecza nas przed „Race Condition”. Nie mniej za nim przejdziemy do dalszej walki o poprawną prace naszej aplikacji pozwolę sobie na kilka uwag które mogą być pomocne przy tworzeniu zmiennej funkcjonalnej.

Dlaczego nie jesteśmy zabezpieczeni przed „Race condition” ?

Wystarczy sobie wyobrazić następującą sytuację:

Dwie równoległe pętle korzystają z naszej zmiennej funkcjonalnej. Pętle te pobierają dane ze zmiennej poleceniem „Get” dokonują modyfikacji a następnie wpisują dane do zmiennej poleceniem „SET”. Wyobraźmy sobie teraz że realizujemy w ten sposób licznik iteracji obu pętli.

Rysunek 2. Race condition

Wynik będzie oczywiście niepoprawny. W takim wypadku zalecaną praktyką jest identyfikacja części kodu odpowiedzialnego za błędne wyniki i dołączenie go jako kodu wewnętrznego FGV. Kod taki nazywamy ogólnie „Action Engine”. Rysunek 3 przedstawia przykładowe polecenie FGV rozwiązujące powyższy problem z hermetyzacją kodu.

Rysunek 3. Hermetyzacja kodu

Jaki jest właściwy tryb egzekucji FGV ?

Wykonanie kodu SubVI jest domyślnie ustawione bez opcji Reentrand. I tak powinno pozostać ponieważ opcja „Reentrant” pozwala na uruchomienie wielu instancji SubVi i pracy jako oddzielne podprogramy  co w przypadku zmiennej globalnej czyniło by ją bezużyteczną.

Czy istnieje lepsza metoda ?

I tak i nie. Obecnie nie znajdziemy takiego problemu który nie dałby się rozwiązać w inny sposób. Do dyspozycji mamy bardzo elastyczne narzędzia jak DVR (Data Value Reference) wraz z całą obiektowością LabVIEW na przykład rozwiązania oparte na CVT (Current Value Table). Jeśli od naszej zmiennej nie wymagamy ekstremalnej wydajności FVG wydaje się być dobry osadzonym w świadomości innych programistów rozwiązaniem które będzie współistnieć z pozostałymi możliwościami.

© 2011-2017 LabVIEW Fan Group