I read a blog about Readers-Writer Lock here Implementing reader-writer locks last week. The original code was written in Golang. And I attempted to rewrite the code in Julia.
The reader count based implementation is straight forward in Julia:
mutable struct ReaderCountRWLock
m::Threads.Mutex
reader_count::Int
ReaderCountRWLock() = new(Threads.Mutex(), 0)
end
function read_lock(l::ReaderCountRWLock)
lock(l.m) do
l.reader_count += 1
end
end
function read_unlock(l::ReaderCountRWLock)
lock(l.m) do
l.reader_count -= 1
if l.reader_count < 0
error("reader count negative")
end
end
end
function write_lock(l::ReaderCountRWLock)
while true
lock(l.m)
if l.reader_count > 0
unlock(l.m)
else
break
end
end
end
function write_unlock(l::ReaderCountRWLock)
unlock(l.m)
end
But for the last part in that blog, A more efficient writer-preferring RW lock, it mentions that there’s a more efficient implementation in Golang here https://golang.org/src/sync/rwmutex.go?s=987:1319#L18 Unfortunately, I don’t know what’s the equivalent function of runtime_SemacquireMutex in Julia.
So my question is: how to implement the equivalent Readers-Writer lock in Julia?
I’ve recently had the same need and I was looking for something like that but I found nothing. I didn’t want to block other threads with every read operation, so the hack I’m using right now is a semaphore with a max. capacity equal to the number of readers:
sem = Semaphore(num_readers)
read_lock(sem::Semaphore) = acquire(sem)
read_unlock(sem::Semaphore) = release(sem)
function write_lock(sem::Semaphore)
for i=1:num_readers
acquire(sem)
end
end
function write_unlock(sem::Semaphore)
for i=1:num_readers
release(sem)
end
end
You can also create a reader-writer lock from multiple channels, although it is rather a mental exercise than a useful implementation: Locks · Reagents (It should be a totally valid one, though)