# Pool of locks?

**URL:** <https://discourse.julialang.org/t/pool-of-locks/132457>\
**Category:** General Usage\
**Tags:** multithreading\
**Created:** [September 17, 2025, 9:16am UTC](https://discourse.julialang.org/t/pool-of-locks/132457 "2025-09-17T09:16:07Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![user664303](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/user664303/32/37843_2.png) [@user664303](https://discourse.julialang.org/u/user664303)\
**Post date:** [September 17, 2025, 9:16am UTC](https://discourse.julialang.org/t/pool-of-locks/132457/1 "2025-09-17T09:16:07Z")

</div>

I want to parallelize a for loop across multiple threads. Each thread will update some shared memory, so I need to avoid concurrent access of that memory.

One way is to simply give each thread a copy of the shared memory, and aggregate at the end. What tools are there in Julia to make this very simple?

If the shared memory is quite large, and the access time is a relatively small proportion of the overall computation, and I have N threads, then a better approach might be to have n copies of the shared memory and a pool of n write locks, where n \< N. Each thread can then request a write lock when it needs to access the shared memory, and the lock returns the first shared memory instance available. The copies of shared memory still need to be aggregated at the end. Is such a mechanism available in Julia, currently?

---

<div class="post-metadata">

**Author:** ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)\
**Post date:** [September 17, 2025, 11:58am UTC](https://discourse.julialang.org/t/pool-of-locks/132457/2 "2025-09-17T11:58:12Z")

</div>

There are various techniques available in OhMyThreads.jl, though I don’t know if they fit your use case. You can e.g. set up task local memory quite easily.

I’m not aware of something premade for your second suggestion, keeping a pool around, but there are locks(`ReentrantLock`, `@lock`), semaphores(`Base.Semaphore`, `Base.acquire`, `Base.release`) and atomic operations around (`Threads.Atomic`, `@atomic`) to handle low-level synchronization. It’s also possible to handle the synchronization via a `Channel`

```julia-auto
mem = [fill(0.0, 1000) for _ in 1:10] # memory buffers
store = Channel{eltype(mem)}(length(mem))
# fill channel
for m in mem
    put!(store, m)
end

```

Then, when you need a memory buffer, just `take!` it, and put it back when finished.

```julia-auto
mymem = take!(store)
... do stuff to mymem...
put!(store, mymem)

```

And close it when done:

```julia-auto
close(store)

```

---

<div class="post-metadata">

**Author:** ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)\
**Post date:** [September 17, 2025, 12:13pm UTC](https://discourse.julialang.org/t/pool-of-locks/132457/3 "2025-09-17T12:13:49Z")

</div>

The `Channel` approach as suggested works well; I’ve used it before.

Also, read this section of the OhMyThreads.jl docs: [Per-thread allocation](https://juliafolds2.github.io/OhMyThreads.jl/stable/literate/tls/tls/#Per-thread-allocation) (and possibly also the above section).

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 17, 2025, 12:14pm UTC](https://discourse.julialang.org/t/pool-of-locks/132457/4 "2025-09-17T12:14:15Z")

</div>

OhMyThreads.jl is the most versatile way to go. The simplest from a point of view of basic Julia usage, is, I think, to use ChunkSplitters.jl directly:

```julia-repl
julia> using ChunkSplitters, Base.Threads

julia> function parallel_sum(x; ntasks=Threads.nthreads())
           partial_sum = zeros(ntasks)
           @threads for (ichunk, chunk) in enumerate(chunks(x; n=ntasks))
               for val in chunk
                   partial_sum[ichunk] += val
               end
           end
           return sum(partial_sum)
       end
parallel_sum (generic function with 1 method)

julia> x = rand(1000);

julia> sum(x)
489.82387373881164

julia> parallel_sum(x)
489.8238737388118

```

---

<div class="post-metadata">

**Author:** ![user664303](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/user664303/32/37843_2.png) [@user664303](https://discourse.julialang.org/u/user664303)\
**Post date:** [September 17, 2025, 3:01pm UTC](https://discourse.julialang.org/t/pool-of-locks/132457/5 "2025-09-17T15:01:39Z")

</div>

> [@sgaure](#):
>
> It’s also possible to handle the synchronization via a `Channel`

This seems ideal for my second case. Thanks!
