Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to use @spawn :samepool for using the same threadpool as the caller #57109

Merged
merged 3 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ New language features
- actual running time for the task (`Base.Experimental.task_running_time_ns`), and
- wall-time for the task (`Base.Experimental.task_wall_time_ns`).
- Support for Unicode 16 ([#56925]).
- `Threads.@spawn` now takes a `:samepool` argument to specify the same threadpool as the caller.
`Threads.@spawn :samepool foo()` which is shorthand for `Threads.@spawn Threads.threadpool() foo()` ([#57109])

Language changes
----------------
Expand Down
16 changes: 12 additions & 4 deletions base/threadingconstructs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -440,10 +440,11 @@ function _spawn_set_thrpool(t::Task, tp::Symbol)
end

"""
Threads.@spawn [:default|:interactive] expr
Threads.@spawn [:default|:interactive|:samepool] expr

Create a [`Task`](@ref) and [`schedule`](@ref) it to run on any available
thread in the specified threadpool (`:default` if unspecified). The task is
thread in the specified threadpool: `:default`, `:interactive`, or `:samepool`
to use the same as the caller. `:default` is used if unspecified. The task is
allocated to a thread once one becomes available. To wait for the task to
finish, call [`wait`](@ref) on the result of this macro, or call
[`fetch`](@ref) to wait and then obtain its return value.
Expand All @@ -468,6 +469,9 @@ the variable's value in the current task.
!!! compat "Julia 1.9"
A threadpool may be specified as of Julia 1.9.

!!! compat "Julia 1.12"
The same threadpool may be specified as of Julia 1.12.

# Examples
```julia-repl
julia> t() = println("Hello from ", Threads.threadid());
Expand All @@ -486,7 +490,7 @@ macro spawn(args...)
ttype, ex = args
if ttype isa QuoteNode
ttype = ttype.value
if ttype !== :interactive && ttype !== :default
if !in(ttype, (:interactive, :default, :samepool))
throw(ArgumentError(LazyString("unsupported threadpool in @spawn: ", ttype)))
end
tp = QuoteNode(ttype)
Expand All @@ -507,7 +511,11 @@ macro spawn(args...)
let $(letargs...)
local task = Task($thunk)
task.sticky = false
_spawn_set_thrpool(task, $(esc(tp)))
local tp = $(esc(tp))
if tp == :samepool
tp = Threads.threadpool()
end
_spawn_set_thrpool(task, tp)
if $(Expr(:islocal, var))
put!($var, task)
end
Expand Down
9 changes: 9 additions & 0 deletions test/threadpool_use.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ using Base.Threads
@test fetch(Threads.@spawn Threads.threadpool()) === :default
@test fetch(Threads.@spawn :default Threads.threadpool()) === :default
@test fetch(Threads.@spawn :interactive Threads.threadpool()) === :interactive
@test fetch(Threads.@spawn :samepool Threads.threadpool()) === Threads.threadpool()
@sync for tp in [:interactive, :default]
Threads.@spawn tp begin
@test fetch(Threads.@spawn :samepool Threads.threadpool()) === Threads.threadpool()
end
end
wait(Threads.@spawn :interactive begin
@test fetch(Threads.@spawn :samepool Threads.threadpool()) === Threads.threadpool()
end)
tp = :default
@test fetch(Threads.@spawn tp Threads.threadpool()) === :default
tp = :interactive
Expand Down
Loading