Odczytanie zmiennej i wyniku funkcji
Żółwie w POOL są aktywnymi obiektami posiadającymi składowe zmienne, właściwości i funkcje. Każdy żółw-obiekt
posiada własną kolejkę zadań (wątek). Jeśli funkcja składowa jednego żółwia jest wywołana przez innego żółwia,
wykonywanie funkcji jest równolegle z kodem wywołującym. Tak wywołane funkcje są traktowane jako osobne zadania
i są ustawiane w kolejce w kolejności, w jakiej wystąpiły wywołania. W ten sam sposób traktowane są także
wywołania instrukcji, które zmieniają stan żółwia, np.:
forward, setpencolor
.
Wykonanie programu zostanie wstrzymane przy pierwszej próbie użycia wyniku zadania innego żółwia, jeśli
wynik ten nie jest jeszcze gotowy (przykłady 1 i 2).
W ordóżnieniu od wywołań funkcji, odczytanie zmiennych i właściwości żółwia odbywa się w ramach zadania żółwia
wykonującego operację odczytu. Nie jest tworzone równoległe zadanie, a wynik jest dostępny natychmiast. W ten sposób
możliwe jest monitorowanie na bieżąco wartości zmiennych i właściwości (np.: pos,
pencolor
), nawet jeśli monitorowany żółw wykonuje długotrwałe zadanie (przykład 3).
Aby odczytywać zmienne i właściwości w sposób zsynchronizowany z zadaniami żółwia, należy zdefiniować funkcje dostępu, np.:
to model
"x := 5
to getx op :x end
to getpos op pos end
end
Przykład 1:
Program zapisuje wynik funkcji silnia
w tablicy :y
.
Ponieważ elementy tablicy są używane dopiero w poleceniu print :y
,
możliwe jest wykonanie całej pętli for
i uruchomienie równoległych
obliczeń funkcji.
to silnia :x
(print who :x)
if :x > 1 [op :x * silnia :x - 1]
op 1
end
"n := 3
"y := newarray :n
"t := (anewturtles :n)
for [i 1 :n] [:y,:i := (silnia :i+2) @ :t,:i]
print :y
Rezultat wykonania:
Kolejność pojawienia się napisów może być różna dla każdego uruchomienia, poza wynikiem "{6 24 120}", który zawsze
wypisywany jest jako ostatni.
t1 3
t2 4
t3 5
t1 2
t2 3
t3 4
t1 1
t2 2
t3 3
t2 1
t3 2
t3 1
{6 24 120}
Przykład 2:
Program zapisuje wynik funkcji fn
w zmiennej :p
.
Ponieważ wynik funkcji jest używany przez program dopiero w ostatnim poleceniu, możliwe jest wykonanie wcześniejszych
poleceń w trakcie długotrwałego wykonania funkcji.
to model :param
to fn :x
(print "start "fn :x)
wait 2000
let "wynik :x * :param
(print "wynik "gotowy)
op :wynik
end
end
"t := (newt $model 2)
(print "wywołaj "funkcję)
"p := (fn 5) @ :t
repeat 3 [wait 200 (print "równoległy "kod repcount)]
print "czekaj...
(print "użyj :p)
Rezultat wykonania:
wywołaj funkcję
start fn 5
równoległy kod 1
równoległy kod 2
równoległy kod 3
czekaj...
wynik gotowy
użyj 10
Przykład 3:
Funkcja zmieniaj_q
jest czasochłonna, w trakcie jej wykonania zmienia się wartość zmiennej
:q
. Program wywołuje funkcję i następnie monitoruje
zmiany wartości :q
, równolegle z wykonaniem funkcji.
to model :param
to zmieniaj_q
repeat 3 [
wait 200
"q += 1
wait 200
]
"koniec := true
end
"koniec := false
"q := :param
end
"t := (newt $model 0)
"test := :q @ :t
zmieniaj_q @ :t
while not :koniec @ :t [
"n := :q @ :t
if :test <> :n ["test := :n (print "zmiana :n repcount)]
wait 10
]
print "stop
Rezultat wykonania:
zmiana 1 22
zmiana 2 61
zmiana 3 101
stop
Zobacz także:
Zmienne lokalne, globalne, współdzielone
Klasy i dziedziczenie
@ (dostęp do składowych)
Spis treści