Execute instructions with exclusive access to a variable

lock name [instructions]

Locks the access to a variable with the name. If the variable was already locked by another turtle then lock causes the the program to wait until the variable is released.

Example:
Functions take_some and return_all should be executed by a single turtle at a time in order to ensure that sum of the shared variable :tot and all the :my variables is constant. If lock is disabled (lines marked with stars are commented out) then the sum will vary randomly.
Also the sum is calculated inside the lock code block. This ensures that :tot and :my are not modified during the calculations.

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 [   ;***** change value of :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 [  ;*** count the sum of :my *****
    foreach "ti :t ["sum += :my @ :ti]
      (print :sum + :tot :sum :tot)
  ]            ;******************************
] 300

Output (version 1, no changes in the code):

100 100 0
100 11 89
100 76 24
100 72 28
100 79 21
100 76 24
...

Ourput (version 2, code with lock disabled):

100 100 0
195 168 27
290 288 2
75 40 35
70 43 27
6 6 0
...

See also:

Variables, access to data
Classes and inheritance

Tableof Content