# How to implement an efficient Readers-Writer lock?

**URL:** https://discourse.julialang.org/t/how-to-implement-an-efficient-readers-writer-lock/27446
**Category:** Performance
**Tags:** multithreading
**Created:** [August 12, 2019, 9:20am UTC](https://discourse.julialang.org/t/how-to-implement-an-efficient-readers-writer-lock/27446 "2019-08-12T09:20:04Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![findmyway](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/findmyway/32/4946_2.png) [@findmyway](https://discourse.julialang.org/u/findmyway)
#### Post date: [August 12, 2019, 9:20am UTC](https://discourse.julialang.org/t/how-to-implement-an-efficient-readers-writer-lock/27446/1 "2019-08-12T09:20:04Z")

</div>

I read a blog about Readers-Writer Lock here [Implementing reader-writer locks](https://eli.thegreenplace.net/2019/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:

```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](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?

---

<div class="post-metadata">

### Author: ![dcasbol](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dcasbol/32/18756_2.png) [@dcasbol](https://discourse.julialang.org/u/dcasbol)
#### Post date: [November 12, 2021, 10:53am UTC](https://discourse.julialang.org/t/how-to-implement-an-efficient-readers-writer-lock/27446/2 "2021-11-12T10:53:14Z")

</div>

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:

```julia
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

```

---

<div class="post-metadata">

### Author: ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)
#### Post date: [November 12, 2021, 10:25pm UTC](https://discourse.julialang.org/t/how-to-implement-an-efficient-readers-writer-lock/27446/3 "2021-11-12T22:25:58Z")

</div>

I’m not sure if this is the right question to ask, because I believe it is notoriously difficult to get this right.

---

<div class="post-metadata">

### Author: ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)
#### Post date: [November 13, 2021, 2:21am UTC](https://discourse.julialang.org/t/how-to-implement-an-efficient-readers-writer-lock/27446/4 "2021-11-13T02:21:50Z")

</div>

> [@dcasbol](#):
>
> ```julia
> function write_lock(sem::Semaphore)
> for i=1:num_readers
> acquire(sem)
> end
> end
> 
> ```

Doesn’t it deadlock when there are two or more writers?

---

<div class="post-metadata">

### Author: ![dcasbol](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dcasbol/32/18756_2.png) [@dcasbol](https://discourse.julialang.org/u/dcasbol)
#### Post date: [November 15, 2021, 12:16pm UTC](https://discourse.julialang.org/t/how-to-implement-an-efficient-readers-writer-lock/27446/5 "2021-11-15T12:16:54Z")

</div>

Yes. It was thought to be used with a single writer. With +1 writers it gets trickier and I wouldn’t know how to solve it off the top of my head.

---

<div class="post-metadata">

### Author: ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)
#### Post date: [November 16, 2021, 7:50pm UTC](https://discourse.julialang.org/t/how-to-implement-an-efficient-readers-writer-lock/27446/6 "2021-11-16T19:50:48Z")

</div>

So let me be more specific about the questions I would ask:

- is there any Julia support for OS provided rw-locks?
- if not, are rw-locks of any value with regard to the multi threading and distribution implementation of Julia (aka `Threads` and `Distributed`?

---

<div class="post-metadata">

### Author: ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)
#### Post date: [November 17, 2021, 12:14am UTC](https://discourse.julialang.org/t/how-to-implement-an-efficient-readers-writer-lock/27446/7 "2021-11-17T00:14:43Z")

</div>

You wouldn’t want to use locks for OS native threads. You’d need to yield to Julia scheduler and not to OS while waiting.

I don’t think it’d be hard to implement a simple reader-writer lock based on `Threads.Condition`. Maybe look at [The Art of Multiprocessor Programming - 2nd Edition](https://www.elsevier.com/books/the-art-of-multiprocessor-programming/herlihy/978-0-12-415950-1) or [An Error Occurred Setting Your User Cookie](https://www.morganclaypool.com/doi/abs/10.2200/S00499ED1V01Y201304CAC023)

You can also create a reader-writer lock from multiple channels, although it is rather a mental exercise than a useful implementation: [Locks · Reagents](https://juliaconcurrent.github.io/Reagents.jl/dev/tutorials/locks/#Reader-writer-lock) (It should be a totally valid one, though)
