Zmienne współdzielone
Zmienna współdzielona jest dostępna dla wszystkich żółwi, we wszystkich funkcjach, niezależnie od tego, który żółw
ją utworzył i na jakim poziomie zagnieżdżenia funkcji. Zmienne współdzielone pod wieloma względami odpowiadają
zmiennym statycznym występującym w innych językach programowania.
Używaj zmiennych współdzielonych aby łatwo udostępnić dane wszystkim żółwiom, ale zauważ: zmienne współdzielone są
przeglądane podczas odczytu dopiero gdy nazwa zmiennej nie została znaleziona wśród zmiennych lokalnych i globalnych
- dostęp do zmiennych współdzielonych jest najwolniejszy.
Przykład 1:
Żółwie w programie sprawdzają cyklicznie wartość zmiennej współdzielonej :s
.
Żółw kończy swoje działanie kiedy zauważy wartość true
.
shared "s
"s := false
"t := newturtles 3 [
let "cyk timer [
if :s [
(print who "skończył)
destroy
]
(print who :iter)
] 300
]
wait 1500
print "stop
"s := true
Rezultat wykonania:
Zauważ, że napisy "nazwa skończył" mogą nie pojawić się bezpośrednio po napisie "stop" - pomiędzy wykonaniem instrukcji
print "stop
i
"s := true
mogą zostać wykonane instrukcje innych żółwi.
t2 1
t1 1
t3 1
t2 2
t1 2
t3 2
t2 3
t1 3
t3 3
t2 4
t1 4
t3 4
t2 5
t1 5
t3 5
t2 6
stop
t1 6
t3 6
t2 skończył
t1 skończył
t3 skończył
Przykład 2:
Program ilustruje zarezerwowanie wyłącznego dostępu do zmiennej. Aby całkowita suma zmiennej współdzielonej
:tot
i zmiennych :my
w poszczególnych żółwiach była stała, funkcje take_some
i return_all
mogą być wykonywane tylko przez jednego żółwia w danym momencie. Wyłączenie instrukcji lock
(zakomentowanie linijek oznaczonych gwiazdkami) spowoduje losową zmianę całkowitej sumy.
Równierz obliczanie sumy jest wykonane w bloku lock
, co zapewnia
blokadę zmian wartości :tot
i :my
.
to model
to take_some
if :tot > 0 [
let "x (random :tot) + 1
"tot -= :x
"my += :x
]
end
to return_all
"tot += :my
"my := 0
end
"my := 0
let "t timer [
lock "tot [
ifelse (random 2) = 0 [take_some] [return_all]
]
] (random 10) + 1
end
shared "tot
"tot := 100
"t := newturtles 10 $model
"chk := timer [
let "sum 0
lock "tot [
foreach "ti :t ["sum += :my @ :ti]
(print :sum + :tot :sum :tot)
]
] 300
Rezultat wykonania (wariant 1, kod bez zmian):
100 100 0
100 11 89
100 76 24
100 72 28
100 79 21
100 76 24
...
Rezultat wykonania (wariant 2, kod z wyłączoną instrukcją lock
):
100 100 0
195 168 27
290 288 2
75 40 35
70 43 27
6 6 0
...
Zobacz także:
Typy danych
Zmienne, dostęp do danych
lock - wykonaj instrukcje z wyłącznym dostęp do zmiennej
Spis treści