# Barrier to synchronize threads

**URL:** https://discourse.julialang.org/t/barrier-to-synchronize-threads/130235
**Category:** General Usage
**Created:** [June 26, 2025, 12:56pm UTC](https://discourse.julialang.org/t/barrier-to-synchronize-threads/130235 "2025-06-26T12:56:35Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![dubosipsl](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dubosipsl/32/52998_2.png) [@dubosipsl](https://discourse.julialang.org/u/dubosipsl)
#### Post date: [June 26, 2025, 12:56pm UTC](https://discourse.julialang.org/t/barrier-to-synchronize-threads/130235/1 "2025-06-26T12:56:36Z")

</div>

Hello all,  
AFAIK there is now built-in way to synchronize Julia threads at a barrier (think OpenMP Barrier).  
The expected functionality is as follows:

```julia
function test_barrier(nt, ns)
    @sync begin
        b = Barrier(nt)
        for rank in 1:nt
            @spawn for i in 1:ns
                println("Task $rank at step $i")
                wait_at_barrier(rank, b)
            end
        end
    end
end

test_barrier(40,4)

```

This is supposed to spawn 40 tasks performing a work in 4 stages. Each task waits until others have completed a given stage before moving to the next stage.

After some back-and forth with an AI I arrived at:

```julia
using Base.Threads

struct Barrier
    count::Int
    arrived::Threads.Atomic{Int}
    release::Channel{Nothing}
end

Barrier(n::Int) = Barrier(n, Atomic{Int}(0), Channel{Nothing}(n))

function wait_at_barrier(rank, b::Barrier)
    (; release, arrived, count) = b
    if atomic_add!(arrived, 1) == count - 1
        arrived[] = 0 # before releasing other threads
        for _ in 1:count
            put!(release, nothing)
        end
    end
    return take!(release)
end

```

Unfortunately this hangs…  
Anybody knows of a better way ?

Thanks

---

<div class="post-metadata">

### Author: ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)
#### Post date: [June 26, 2025, 1:07pm UTC](https://discourse.julialang.org/t/barrier-to-synchronize-threads/130235/2 "2025-06-26T13:07:14Z")

</div>

I think OhMyThreads.jl has a barrier implementation: [Internal · OhMyThreads.jl](https://juliafolds2.github.io/OhMyThreads.jl/stable/refs/internal/#OhMyThreads.Tools.SimpleBarrier)

Base also has Semaphores [Tasks · The Julia Language](https://docs.julialang.org/en/v1/base/parallel/#Base.Semaphore)

---

<div class="post-metadata">

### Author: ![dubosipsl](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dubosipsl/32/52998_2.png) [@dubosipsl](https://discourse.julialang.org/u/dubosipsl)
#### Post date: [June 26, 2025, 6:18pm UTC](https://discourse.julialang.org/t/barrier-to-synchronize-threads/130235/3 "2025-06-26T18:18:36Z")

</div>

`SimpleBarrier` does the job, thanks !  
Any chance this becomes part of the official API ?

---

<div class="post-metadata">

### Author: ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)
#### Post date: [June 26, 2025, 8:37pm UTC](https://discourse.julialang.org/t/barrier-to-synchronize-threads/130235/4 "2025-06-26T20:37:25Z")

</div>

Here is a solution using Channels

```julia
struct Barrier
    count::Int
    chan::Channel{Channel{Nothing}}
end

function Barrier(n::Int)
    ch = Channel{Channel{Nothing}}()
    @spawn begin 
        while true
            acks = [take!(ch) for i in 1:n]
            for bc in acks
                put!(bc, nothing)
            end
        end
    end
    Barrier(n, ch)
end

function wait_on_barrier(b::Barrier)
    bc = Channel{Nothing}()
    put!(b.chan, bc)
    take!(bc)
end

```

Imho, channels are a very nice and underappreciated synchronization primitive.
