# Thread safe buffer correctness

**URL:** <https://discourse.julialang.org/t/thread-safe-buffer-correctness/60183>\
**Category:** General Usage\
**Tags:** multithreading\
**Created:** [April 28, 2021, 5:24pm UTC](https://discourse.julialang.org/t/thread-safe-buffer-correctness/60183 "2021-04-28T17:24:02Z")\
**Posts on this page:** 1\
**Showing post:** 5

<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:** [April 28, 2021, 7:58pm UTC](https://discourse.julialang.org/t/thread-safe-buffer-correctness/60183/5 "2021-04-28T19:58:24Z")

</div>

For `Channel`-based producer-consumer approach with consumer-local buffer reuse, see the first example in [Pattern for managing thread local storage? - #2 by tkf](https://discourse.julialang.org/t/pattern-for-managing-thread-local-storage/54023/2)

This pattern is very handy and performs reasonably well in many situations. But, since the whole purpose of `Channel` is to serialize the access, it’s not really the best approach. If your input collection is [supported by SplittablesBase.jl](https://github.com/JuliaFolds/SplittablesBase.jl#supported-collections), FLoops.jl’s [`@init`](https://juliafolds.github.io/FLoops.jl/dev/howto/parallel/#private-variables) can be useful.

But, if you need a buffer pool that works outside producer-consumer pattern or parallel loop, I see that something like `SafeBuffer` in the OP could be handy. One way to simplify the synchronization is:

```julia
struct BufferPool{T}
    buffers::Vector{T}
    condition::Threads.Condition
end

function bufferpool(factory, n::Integer)
    n > 0 || error("need at least one buffer; got n = $n")
    return BufferPool([factory() for _ in 1:n], Threads.Condition())
end

function withbuffer(f, pool::BufferPool)
    b = lock(pool.condition) do
        while isempty(pool.buffers)
            wait(pool.condition)
        end
        pop!(pool.buffers)
    end
    try
        f(b)
    finally
        lock(pool.condition) do
            push!(pool.buffers, b)
            notify(pool.condition)
        end
    end
end

```

---

_[View the full topic](https://discourse.julialang.org/t/thread-safe-buffer-correctness/60183)._
