# Worker thread setup in Julia compared to C++/pthreads

**URL:** <https://discourse.julialang.org/t/worker-thread-setup-in-julia-compared-to-c-pthreads/56630>\
**Category:** New to Julia\
**Created:** [March 6, 2021, 8:54pm UTC](https://discourse.julialang.org/t/worker-thread-setup-in-julia-compared-to-c-pthreads/56630 "2021-03-06T20:54:46Z")\
**Posts on this page:** 1\
**Showing post:** 2

<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:** [March 6, 2021, 10:50pm UTC](https://discourse.julialang.org/t/worker-thread-setup-in-julia-compared-to-c-pthreads/56630/2 "2021-03-06T22:50:49Z")

</div>

> [@paulmelis](#):
>
> Either I have all worker threads active but the main thread blocked, or I need to use W-1 worker threads to get the main thread to run.

To avoid the main OS thread (`threadid() == 1`) to be blocked, you’d need to start `nthreads() - 1` workers, as you mentioned. A simple solution may be to start Julia with `julia -t$number_of_cpus_plus_one` and use something like

```julia
function foreach_on_non_primary(f, input::Channel)
    workers = Threads.Atomic{Int}(0)
    @sync for _ in 1:Threads.nthreads()
        Threads.@spawn if Threads.threadid() > 1
            Threads.atomic_add!(workers, 1)
            for x in input
                f(x)
            end
        end
    end
    if workers[] == 0
        # Failed to start workers. Fallback to more robust (less controlled)
        # solution:
        @sync for _ in 1:Threads.nthreads()
            Threads.@spawn for x in input
                f(x)
            end
        end
    end
end

for work in work_source
    push!(work_channel, work)
end
close(work_channel) # instead of sentinel, you can just close it (otherwise deadlock)
foreach_on_non_primary(work_channel) do work
    push!(result_channel, compute(work))
end

```

( **Note to wider audience** : I encourage _not_ using approach like this in released packages. Julia’s parallel task runtime needs to control the task scheduling to make parallel programs _composable._ Manually managing task scheduling like this defeats the design philosophy of Julia’s parallel runtime. On the other hand, if you are writing an _application_ (not library), I don’t think there is a problem in using tricks like this. For more discussion, see the documentation of [`FoldsThreads.TaskPoolEx`](https://juliafolds.github.io/FoldsThreads.jl/dev/#FoldsThreads.TaskPoolEx) and [[ANN] FoldsThreads.jl: A zoo of pluggable thread-based data-parallel execution mechanisms](https://discourse.julialang.org/t/ann-foldsthreads-jl-a-zoo-of-pluggable-thread-based-data-parallel-execution-mechanisms/54662))

I think ThreadPools.jl’s “background threading API” like `bforeach` and `qbforeach` are somewhat equivalent to the function `foreach_on_non_primary` I wrote above. But they are more reliable when it comes to distributing tasks across OS threads if the worker function `f` yields to the scheduler immediately.

> [@paulmelis](#):
>
> But the lack of low-level control over OS-level threads

Note that the lack of _user’s_ control yields the increase in _system’s_ control. This is a key theme in Julia (or maybe rather in any programming systems in general) for unlocking a larger class of optimizations. Indeed, this is quite opposite in philosophy when compared to “systems” language like C++ or glue language like Python. For example, we are looking for even more restricted form of task parallelism (more discussion in my PR: [RFC: Experimental API for may-happen in parallel parallelism by tkf · Pull Request #39773 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/39773)). I agree that Julia’s task parallelism could be confusing if you already are familiar with programming using OS-level threading. But the lack of control is actually there for leaving room for the system to improve the performance.

---

_[View the full topic](https://discourse.julialang.org/t/worker-thread-setup-in-julia-compared-to-c-pthreads/56630)._
