Skip to content

Document assumptions on the iterators for the different Threads.@threads schedulers  #58704

Closed
@draftman9

Description

@draftman9

Julia Version: 1.10.5+0.x64.linux.gnu (installed by juliaup)
OS/Architecture: Linux x86_64, Ubuntu 22.04

The Threads.@threads macro does not seem to support iterating directly over a Channel, as it appears to require a collection that implements the length method. This is a common and intuitive pattern for parallel producer-consumer workflows, and its failure can be surprising.

Minimal Working Example (test.jl)

using Base.Threads

requests = Channel{Int}(3)
put!(requests, 1)
put!(requests, 2)
put!(requests, 3)
close(requests)

Threads.@threads for item in requests
    # Use a lock to prevent garbled output from multiple threads printing at once
    lock(print_lock) do
        println("Thread $(threadid()) took from Channel: $item")
    end
end

Actual Behavior (Error)

Running the code with julia -t 4 test.jl throws a TaskFailedException because the underlying tasks fail with a MethodError.

↪ julia -t 4 test.jl 
ERROR: LoadError: TaskFailedException

    nested task error: MethodError: no method matching length(::Channel{Int64})
    
    Closest candidates are:
      length(::Core.SimpleVector)
       @ Base essentials.jl:770
      length(::LibGit2.GitBlob)
       @ LibGit2 /media/Big/replaceC/.julia/juliaup/julia-1.10.5+0.x64.linux.gnu/share/julia/stdlib/v1.10/LibGit2/src/blob.jl:3
      length(::Core.Compiler.InstructionStream)
       @ Base show.jl:2777
      ...
    
    Stacktrace:
     [1] (::var"#59#threadsfor_fun#3"{var"#59#threadsfor_fun#1#4"{Channel{Int64}}})(tid::Int64; onethread::Bool)
       @ Main ./threadingconstructs.jl:184
     [2] (::var"#59#threadsfor_fun#3"{var"#59#threadsfor_fun#1#4"{Channel{Int64}}})(tid::Int64)
       @ Main ./threadingconstructs.jl:182
     [3] (::Base.Threads.var"#1#2"{var"#59#threadsfor_fun#3"{var"#59#threadsfor_fun#1#4"{Channel{Int64}}}, Int64})()
       @ Base.Threads ./threadingconstructs.jl:154

...and 3 more exceptions.

Stacktrace:
 [1] threading_run(fun::var"#59#threadsfor_fun#3"{var"#59#threadsfor_fun#1#4"{Channel{Int64}}}, static::Bool)
   @ Base.Threads ./threadingconstructs.jl:172
 [2] macro expansion
   @ ./threadingconstructs.jl:220 [inlined]
 [3] top-level scope
   @ /media/Big/folder-by-syncthing/something-fun-by-julia/parallel-dynamic-vs-static/test.jl:219
in expression starting at /media/Big/folder-by-syncthing/something-fun-by-julia/parallel-dynamic-vs-static/test.jl:9

Metadata

Metadata

Assignees

No one assigned

    Labels

    docsThis change adds or pertains to documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions