Hello there,
I was looking for a way to share a consistent state between several local processes that would be more efficient than using channels. I noticed that since I can use CAS operations on any pointer and SharedArrays give me a way to have access to the same memory cell from different processes, I can make a lock with it. Thus SharedMemoryLocks.jl was born.
It provides the SharedMemoryLock
class, which implements a simple non-reentrant spin lock on a memory cell that is shared between processes. It takes an optional pids
parameter, that is passed to the SharedArray
constructor. After that, it can be used as any other lock object.
Here is a simple test example:
pids = addprocs(2)
@everywhere using SharedMemoryLocks
push!(pids, myid())
l = SharedMemoryLock(pids)
arr = SharedArray{Int}(1, init = 0, pids = pids)
function calc(l, arr)
for i in 1:100
lock(l)
v = arr[1]
sleep(0.000000001)
arr[1] = v + 1
unlock(l)
end
end
f1 = @spawnat pids[1] calc(l, arr)
f2 = @spawnat pids[2] calc(l, arr)
fetch(f1)
fetch(f2)
@test arr[1] == 200
I hope it will be a useful primitive for other people too, so tell me what you think!