Logo

Programming-Idioms

This language bar is your friend. Select your favorite languages!

Idiom #33 Atomically read and update variable

Assign to the variable x the new value f(x), making sure that no other thread may modify x between the read and the write.

(def x (atom 0))
(def f inc)
(swap! x f)
#include <mutex>
//declaration
auto mutex = std::mutex{};
auto x = someValue();

//use
{
	auto lock = std::unique_lock{mutex};
	x = f(x);
}
#include <atomic>
std::atomic<int> x{};

auto local_x = x.load();
while(!x.compare_exchange_strong(local_x, f(local_x))) {
	local_x = x.load();
}
private readonly object m_Sync = new object();

lock(m_Sync)
{
    x = f(x);
}
lock (x) {
  x = f(x);	
}
synchronized x = f(x);
x = f(x);
x = f(x)
integer, dimension[*] :: x

critical
  x = f(x)
end critical
import "sync"
var lock sync.Mutex

lock.Lock()
x = f(x)
lock.Unlock()
import Control.Concurrent.MVar
putMVar x . f =<< takeMVar x
let x = f(x)
synchronized(lock){
  x = f(x);
}
$mutex = Mutex::create();
Mutex::lock($mutex);
$x = f($x);
Mutex::unlock($mutex);
Mutex::destroy($mutex);
uses syncobjs;
var
  loc: TCriticalSection;
begin
  loc.Enter;
  try
    x := f(x);
  finally
    loc.Leave;
  end;
end.
use threads;
use threads::shared;
my $x :shared;
$x = 0;

sub my_task {
   my $id = shift;
   for (1 .. 5) {
      sleep 2*rand();
      { # lock scope
         lock($x);
         print "thread $id found $x\n";
         $x = $id;
         sleep 2*rand();
      }
   }
}

threads->create('my_task', $_) for 1 .. 3;
sleep 5 while threads->list(threads::running);
import threading
lock = threading.Lock()

lock.acquire()
try:
	x = f(x)
finally:
	lock.release()
import threading
with threading.Lock():
    x = f(x)
require 'atomic'
x = Atomic.new(0)
x.update { |x| f(x) }
let mut x = x.lock().unwrap();
*x = f(x);

New implementation...
< >
programming-idioms.org