Relation of coroutines, threads, and Tasks

If we are just talking solely about Julia and it’s standard library, the only interface you have to threads are Tasks.

Notice that when you use Thread.@spawn you get a Task:

julia> Threads.@spawn sleep(5)
Task (runnable) @0x00007f3fee5beca0

If you look under the hood, you will see that all Theads.@spawn does is create a Task and sets the sticky property to false.

julia> @macroexpand Threads.@spawn sleep(5)
quote
    #= threadingconstructs.jl:181 =#
    let
        #= threadingconstructs.jl:182 =#
        local var"#3#task" = Base.Threads.Task((()->begin
                            #= threadingconstructs.jl:178 =#
                            sleep(5)
                        end))
        #= threadingconstructs.jl:183 =#
        (var"#3#task").sticky = false
        #= threadingconstructs.jl:184 =#
        if $(Expr(:islocal, Symbol("##sync#41")))
            #= threadingconstructs.jl:185 =#
            Base.Threads.put!(var"##sync#41", var"#3#task")
        end
        #= threadingconstructs.jl:187 =#
        Base.Threads.schedule(var"#3#task")
        #= threadingconstructs.jl:188 =#
        var"#3#task"
    end
end

The interface to threads in Julia is Task-based. Sometimes the Task may run on a different thread if you used Threads.@spawn.

A Channel is used for communicating between Tasks whether be on the same thread or not. If you look in the documentation of Channel you should see a spawn keyword:

If spawn = true, the Task created for func may be scheduled on another thread in parallel, equivalent to creating a task via Threads.@spawn.

1 Like