I’m happy to announce a (breaking) API upgrade to ThreadPools.jl to better separate choices around handling background tasks and handling nonuniform tasks. Many thanks to @tkf and @ianshmean and many others who contributed to the ideas.
ThreadPools.jl is a simple package for thread parallelization that exposes a few macros and functions that mimic
Base.map , and
Base.foreach. These macros/functions handle cases that the built-in functions are not always well-suited for:
- Groups of tasks that the user wants to keep off of the primary thread
- Groups of tasks that are very nonuniform in duration
For the first case, ThreadPools exposes a
@bthreads (“background threads”) macro that behaves identically to
Threads.@threads , but keeps the primary thread job-free. For the second case, the package exposes a
@qthreads (“queued threads”) macro. This macro queues up the jobs before thread assignment, only starting a new job when a job on any previous thread has finished. The background version of the same is the
@qbthreads (“queued background threads”) macro. Versions of
foreach with the same prefixes are also available:
|Foreground (primary allowed)||Background (primary forbidden)|
The package also exposes a lower-level
@pspawnat macro that mimics the
Base.Threads.@spawn macro, but allows direct thread assignment for users who want to develop their own scheduling.
There are also logging versions of each of the above:
julia> using Plots pool = logpforeach(x -> sleep(0.01*x), 1:64); plot(pool)
pool = logqforeach(x -> sleep(0.01*x), 1:64); plot(pool)
Note that the above examples demonstrate the two scheduling strategies far better than I can describe.
There may be times where the default macros don’t quite do what you want. For those cases, a composable API is exposed. For example, perhaps we want to limit usage to only two threads off of the primary:
julia> pwith(ThreadPools.QueuePool(2,2)) do pool pforeach(pool, x -> println((x,Threads.threadid())), 1:8) end; (2, 2) (1, 3) (3, 2) (4, 3) (5, 2) (6, 3) (7, 2) (8, 3)
Here, only threads 2 and 3 are used (in this case, on an 8-thread machine).
Anyway, thanks for all the early-adopter inputs, and I hope that some find the package useful. Feel free to submit issues at ThreadPools.jl if you find problems or have requests. Cheers, all!