Multi-Threading
Start Julia with threads: julia -t auto (or JULIA_NUM_THREADS).
Start Julia with threads: julia -t auto (or JULIA_NUM_THREADS).
Threads.nthreads(), Threads.threadid()
# Parallel loop
results = zeros(100)
Threads.@threads for i in 1:100
results[i] = expensive(i) # each iteration writes its own slot: safe
end
# Task-based parallelism (composable, dynamic scheduling)
function psum(v)
chunks = Iterators.partition(v, length(v) ÷ Threads.nthreads())
tasks = [Threads.@spawn sum(c) for c in chunks]
sum(fetch.(tasks))
end
# Parallel recursive fib
function pfib(n)
n < 25 && return fib(n)
t = Threads.@spawn pfib(n - 1)
return pfib(n - 2) + fetch(t)
end28.1 Avoiding data races
Don't index per-thread buffers with threadid() (tasks can migrate); allocate per-task state instead.
total = Threads.Atomic{Int}(0)
Threads.@threads for i in 1:1000
Threads.atomic_add!(total, i)
end
total[]
lk = ReentrantLock()
acc = Float64[]
Threads.@threads for i in 1:10
v = i^2
lock(lk) do
push!(acc, v) # push! on a shared array needs a lock
end
end
mutable struct Counter; @atomic n::Int; end # atomic fields (1.7+)28.2 Higher-level threading packages
OhMyThreads.jl (tmap, tforeach, treduce), ThreadsX.jl (parallel sum, map, sort), FLoops.jl / Folds.jl (transducer-based), Polyester.jl (@batch, low overhead). Also multithreaded BLAS (BLAS.set_num_threads).