# How does Julia Async Task Scheduler work?

**URL:** <https://discourse.julialang.org/t/how-does-julia-async-task-scheduler-work/96675>\
**Category:** New to Julia\
**Tags:** question, async\
**Created:** [March 27, 2023, 8:11pm UTC](https://discourse.julialang.org/t/how-does-julia-async-task-scheduler-work/96675 "2023-03-27T20:11:24Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![defect](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/defect/32/42597_2.png) [@defect](https://discourse.julialang.org/u/defect)\
**Post date:** [March 27, 2023, 8:11pm UTC](https://discourse.julialang.org/t/how-does-julia-async-task-scheduler-work/96675/1 "2023-03-27T20:11:24Z")

</div>

I want to understand how the Julia task scheduler works. Like I get how the Python asyncio async mechanism works, but I find myself unable to find anything about that topic in julia.  
I know you don’t have to annotate the functions separately. I’ve also tried to figure out if the functions are compiled separately as an async variant, but if I did not make any errors, they are not.  
I’ve already tried to get to know the async scheduler the julia GitHub, but that didn’t help me very much either.

So my question is how does the basic task-scheduler mechanism work?

---

<div class="post-metadata">

**Author:** ![jmair](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmair/32/35117_2.png) [@jmair](https://discourse.julialang.org/u/jmair)\
**Post date:** [March 27, 2023, 9:13pm UTC](https://discourse.julialang.org/t/how-does-julia-async-task-scheduler-work/96675/2 "2023-03-27T21:13:20Z")

</div>

I think async tasks are handled with multithreading. Just spawn a method on a different thread with `Threads.@spawn` to run the method asynchronously which returns a `Task` which can be awaited with the `fetch` method. I.e.:

```julia
task = Threads.@spawn my_func()
result = fetch(task)

```

`@spawn` will launch a task that will be scheduled to run immediately (on a Julia thread) and return to the calling thread with a reference to that task. If you want to await the result you can use the `fetch` function. If the task returns nothing, you can use the `wait` function instead.

If you open Julia with multiple threads (e.g. `julia --threads=4`) you can run the tasks in parallel, not just asynchronously (as long as you have a multicore CPU).

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [March 27, 2023, 9:19pm UTC](https://discourse.julialang.org/t/how-does-julia-async-task-scheduler-work/96675/3 "2023-03-27T21:19:10Z")

</div>

See [Announcing composable multi-threaded parallelism in Julia](https://julialang.org/blog/2019/07/multithreading/#under_the_hood)

Basically, Julia was designed to use multitasking as its fundamental parallelism model based on coroutines in Cilk and Go. Everything is running on a `Task`. You can obtain the current `Task` via `Base.current_task()`.

No the functions are not compiled separately. They are just scheduled to run on another task.

If you want to look at the actual implementation, expand the macros.

```julia
julia> f() = println("Hello world")
f (generic function with 1 method)

julia> @async f()
Hello world
Task (runnable) @0x0000020097e4ee90

julia> @macroexpand @async f()
quote
    #= task.jl:487 =#
    let
        #= task.jl:488 =#
        local var"#5#task" = Base.Task((()->begin
                            #= task.jl:484 =#
                            f()
                        end))
        #= task.jl:489 =#
        if $(Expr(:islocal, Symbol("##sync#48")))
            #= task.jl:490 =#
            Base.put!(var"##sync#48", var"#5#task")
        end
        #= task.jl:492 =#
        Base.schedule(var"#5#task")
        #= task.jl:493 =#
        var"#5#task"
    end
end

```

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [March 27, 2023, 11:26pm UTC](https://discourse.julialang.org/t/how-does-julia-async-task-scheduler-work/96675/4 "2023-03-27T23:26:45Z")

</div>

It’s also worth noting that there are two different ways to spawn new tasks:

1. `@async` which will always run the task on the same hardware thread as the current task, and will only make progress when the current task blocks and yields back to the scheduler;
2. `@spawn` which creates a task that can be run on any hardware thread, so it can make progress while the current task is still working if there are other threads available.

You can synchronize both with `@sync`.
