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 [ ;***** zmiana wartości :tot ********
      ifelse (random 2) = 0 [take_some] [return_all]
    ]           ;***********************************
  ] (random 10) + 1
end

shared "tot ;zmienna dostępna dla wszystkich żółwi
"tot := 100

"t := newturtles 10 $model

"chk := timer [
  let "sum 0
  lock "tot [ ;*** obliczenie sumy :my ***
    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