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 docs on task migration #50047

Merged
Merged
Show file tree
Hide file tree
Changes from 3 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
13 changes: 10 additions & 3 deletions base/threadingconstructs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ julia> Threads.@threads for i in 1:4
5
4
```

!!! note
The thread that a task runs on may change if the task yields, which is known as [`Task Migration`](@ref man-task-migration).
For this reason in most cases it is not safe to use `threadid()` to index into, say, a vector of buffer or stateful objects.

"""
threadid() = Int(ccall(:jl_threadid, Int16, ())+1)

Expand Down Expand Up @@ -229,7 +234,7 @@ For example, the above conditions imply that:
- Write only to locations not shared across iterations (unless a lock or atomic operation is
used).
- The value of [`threadid()`](@ref Threads.threadid) may change even within a single
iteration.
iteration. See [`Task Migration`](@ref man-task-migration)

## Schedulers

Expand Down Expand Up @@ -355,8 +360,10 @@ the _value_ of a variable, isolating the asynchronous code from changes to
the variable's value in the current task.

!!! note
See the manual chapter on [multi-threading](@ref man-multithreading)
for important caveats. See also the chapter on [threadpools](@ref man-threadpools).
The thread that the task runs on may change if the task yields, therefore `threadid()` should not
be treated as constant for a task. See [`Task Migration`](@ref man-task-migration), and the broader
[multi-threading](@ref man-multithreading) manual for further important caveats.
See also the chapter on [threadpools](@ref man-threadpools).

!!! compat "Julia 1.3"
This macro is available as of Julia 1.3.
Expand Down
8 changes: 8 additions & 0 deletions doc/src/manual/multi-threading.md
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,14 @@ threads in Julia:
This may require some transitional work across the ecosystem before threading
can be widely adopted with confidence. See the next section for further details.

## [Task Migration](@id man-task-migration)
IanButterworth marked this conversation as resolved.
Show resolved Hide resolved

After a task starts running on a certain thread (e.g. via [`@spawn`](@ref Threads.@spawn) or
[`@threads`](@ref Threads.@threads)), it may move to a different thread if the task yields.

This means that [`threadid()`](@ref Threads.threadid) should not be treated as constant within a task, and therefore
should not be used to index into a vector of buffers or stateful objects.
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we say "Instead, prefer making judicious use of task_local_storage(), or pass values around as explicit arguments."

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what we should advise is that people use @spawn because @spawned tasks can define and return values.

That's a lot nicer as an API than having users trying to reason about shared buffers, or them trying to reach into and keep track of task_local_storage()s

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could keep this PR as is then figure out the recommended patterns in #48542?


## Safe use of Finalizers

Because finalizers can interrupt any code, they must be very careful in how
Expand Down