- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Description
Julia does need the ability to pin a task to a thread (in our current terminology: make it sticky). This currently happens implicitly for tasks created with Base.@async
to support its semantics. To support those semantics, the parent task must also be made sticky. More precisely, if a newly created task S
is sticky (which they are when created with Task()
or @task
), then whichever task calls schedule(S)
will also be made sticky. A task that calls the AsyncCondition(callback)
constructor (which spawns an @async
task) will become sticky, as will a task that calls Timer(callback)
.
This sort of stickiness-infection ignores threadpool boundaries -- a task created on the default threadpool can end up being stuck to an interactive thread.
We can fix some of these (as we have previously), but we cannot fix them all, due to @async
semantics.
Furthermore, such stickiness-infected tasks are never unstuck. There is this PR which attempts to unstick such tasks, but adds too much overhead.
We should introduce an explicit task pin/unpin interface (see #52108) and deprecate Base.@async
so that all this implicit stickiness and associated cruft can be removed from the runtime.
Activity
kpamnany commentedon Nov 9, 2023
We cannot actually remove
Base.@async
until Julia 2.0 of course, as it would be a breaking change. But deprecating it with a suggestion to:@spawn
and a lock or channel to interact with another task if you wantBase.@async
semantics,Should be possible.
jam-khan commentedon Jan 10, 2024
Hi, I would like to work on this issue. I am a beginner to open-source. If I could get some resources, or similar PR that deprecates something, that would be great! Thanks a lot!
nsajko commentedon Jul 26, 2024
Deemphasizing
@async
in the docs seems like it should come before trying to deprecate it, xref #50356.IanButterworth commentedon Jul 26, 2024
Renaming (deprecating) the
Threads
module toTasks
, which has been discussed, would help generalize the meaning via the formTasks.@spawn
.ancapdev commentedon May 29, 2025
A little late on the discussion here, but I remember when task migration was added to improve scheduling performance and this pinning was added to correct breakages.
I know how this machinery works now, but coming at it fresh my assumptions about async semantics and what I expected and wanted for my needs were different. I never expected async to pin to a particular thread. What I expected from async was that it runs concurrently, but non-overlappingly, with my parent and siblings tasks. I.e., a serial execution context with concurrent cooperative tasks. Pinning to a specific thread is greatly inhibiting on the scheduler, and seems like something you only should need in very specific circumstances dealing with external libraries. However, running multiple independent tasks that execute with exclusion is a very useful directive to simplify safe concurrent programming (e.g., for dealing with IO). Is there appetite for a deeper rethink on this?