# Can I decide if a program needs thread-safety at compile time based on the threads available by the julia process?

**URL:** <https://discourse.julialang.org/t/can-i-decide-if-a-program-needs-thread-safety-at-compile-time-based-on-the-threads-available-by-the-julia-process/137321>\
**Category:** Performance\
**Tags:** multithreading\
**Created:** [May 28, 2026, 3:58pm UTC](https://discourse.julialang.org/t/can-i-decide-if-a-program-needs-thread-safety-at-compile-time-based-on-the-threads-available-by-the-julia-process/137321 "2026-05-28T15:58:13Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [May 28, 2026, 3:58pm UTC](https://discourse.julialang.org/t/can-i-decide-if-a-program-needs-thread-safety-at-compile-time-based-on-the-threads-available-by-the-julia-process/137321/1 "2026-05-28T15:58:13Z")

</div>

i.e. can I do something like

`const needs_thread_safety = Threads.nthreads() == 1 ? false : true`

and then use the constant to compile differently if it is true or false (disabling atomics and/or locks if false)? Or do I risk something?

---

<div class="post-metadata">

**Author:** ![gbaraldi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gbaraldi/32/22101_2.png) [@gbaraldi](https://discourse.julialang.org/u/gbaraldi)\
**Post date:** [May 28, 2026, 4:17pm UTC](https://discourse.julialang.org/t/can-i-decide-if-a-program-needs-thread-safety-at-compile-time-based-on-the-threads-available-by-the-julia-process/137321/2 "2026-05-28T16:17:23Z")

</div>

This will record whatever state it was during parse time. (Top level code in packages don’t get re-executed each process). So you might get stale results

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [May 28, 2026, 4:18pm UTC](https://discourse.julialang.org/t/can-i-decide-if-a-program-needs-thread-safety-at-compile-time-based-on-the-threads-available-by-the-julia-process/137321/3 "2026-05-28T16:18:46Z")

</div>

Note that the zero-argument `nthreads()` only counts the default thread pool, not the interactive one. Not sure if the GC threads are concerned with potential data races in Julia source.

---

<div class="post-metadata">

**Author:** ![penelopeysm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/penelopeysm/32/213172_2.png) [@penelopeysm](https://discourse.julialang.org/u/penelopeysm)\
**Post date:** [May 28, 2026, 5:07pm UTC](https://discourse.julialang.org/t/can-i-decide-if-a-program-needs-thread-safety-at-compile-time-based-on-the-threads-available-by-the-julia-process/137321/4 "2026-05-28T17:07:36Z")

</div>

Maybe of interest: [Threads.nthreads() not a compile-time constant. · Issue #34902 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/34902)

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [May 28, 2026, 5:17pm UTC](https://discourse.julialang.org/t/can-i-decide-if-a-program-needs-thread-safety-at-compile-time-based-on-the-threads-available-by-the-julia-process/137321/5 "2026-05-28T17:17:53Z")

</div>

ok, understood, thank you. Instead constructing `needs_thread_safety` at runtime and then use that to disable locking and atomics (e.g. by creating parameters in a struct related to the number of threads available and use that for disparch) would be okay, right?

---

<div class="post-metadata">

**Author:** ![gbaraldi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gbaraldi/32/22101_2.png) [@gbaraldi](https://discourse.julialang.org/u/gbaraldi)\
**Post date:** [May 28, 2026, 5:35pm UTC](https://discourse.julialang.org/t/can-i-decide-if-a-program-needs-thread-safety-at-compile-time-based-on-the-threads-available-by-the-julia-process/137321/6 "2026-05-28T17:35:43Z")

</div>

Yeah that seems fine

---

<div class="post-metadata">

**Author:** ![penelopeysm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/penelopeysm/32/213172_2.png) [@penelopeysm](https://discourse.julialang.org/u/penelopeysm)\
**Post date:** [May 28, 2026, 7:52pm UTC](https://discourse.julialang.org/t/can-i-decide-if-a-program-needs-thread-safety-at-compile-time-based-on-the-threads-available-by-the-julia-process/137321/7 "2026-05-28T19:52:40Z")

</div>

If it’s of ay interest, what I did on Turing a while back was to make the user specify a flag: [Threadsafe Evaluation – Turing.jl](https://turinglang.org/docs/usage/threadsafe-evaluation/) This becomes a type parameter on the `Model` struct, which means that any downstream code can choose the threaded path and not worry about e.g. type instability. Basically stripped of all the bells and whistles, it looks like this:

```julia
struct Model{threaded} end
Model() = Model{false}()

# API which lets the user opt into the `threaded` path (at runtime).
setthreaded(Model) = Model{true}()

run(::Model{true}) = threaded_sum(1:10)
run(::Model{false}) = sum(1:10)

```

If it’s not in a perf-sensitive path, you could even make the construction of the `Model` type-unstable:

```julia
function Model()
    if Threads.nthreads() > 1
        Model{true}()
    else
        Model{false}()
    end
end
```

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [May 28, 2026, 8:43pm UTC](https://discourse.julialang.org/t/can-i-decide-if-a-program-needs-thread-safety-at-compile-time-based-on-the-threads-available-by-the-julia-process/137321/8 "2026-05-28T20:43:11Z")

</div>

surely of interest! Seems like my preferred way would be the type unstable way, I’m not even sure if in my case the model construction is already type unstable since it’s not performance critical, though, if it is not, I will maybe go with a preference setting instead to preserve type stability.
