Skip to content

Channels throw exception when filled and read from tasks on different threads (sticky = false) #32575

@NHDaly

Description

@NHDaly

I'm opening this PR after some conversation on Slack about using Channels with the new PART multithreaded task runtime. Sorry it took me so long to open this, @JeffBezanson.

The Channel functions sometimes throw an exception when reading values off a channel: cannot switch to task running on another thread

(I read #30186, which looks like it should have added multithreading support for Channels. So it's also possible that I'm actually just not using them correctly?)

Here is an example that seems to (sometimes) trigger the exception:

julia> using Test;

julia> begin
           ch = Channel{Char}(0)
           t = Task(()->for v in "hello" put!(ch, v) end)
           t.sticky = false
           bind(ch, t)
           schedule(t)
           @test String(collect(c)) == "hello"
       end
Error During Test at none:7
  Test threw exception
  Expression: String(collect(c)) == "hello"
  cannot switch to task running on another thread
  Stacktrace:
   [1] check_channel_state at /Users/nathan.daly/src/julia/base/channels.jl:147 [inlined]
   [2] take_unbuffered(::Channel{Char}) at /Users/nathan.daly/src/julia/base/channels.jl:396
   [3] take! at /Users/nathan.daly/src/julia/base/channels.jl:374 [inlined]
   [4] iterate(::Channel{Char}, ::Nothing) at /Users/nathan.daly/src/julia/base/channels.jl:440
   [5] iterate at /Users/nathan.daly/src/julia/base/channels.jl:439 [inlined]
   [6] _collect(::UnitRange{Int64}, ::Channel{Char}, ::Base.HasEltype, ::Base.SizeUnknown) at ./array.jl:569
   [7] collect(::Channel{Char}) at ./array.jl:558
   [8] top-level scope at none:7
   [9] eval at ./boot.jl:330 [inlined]
   [10] repleval(::Module, ::Expr) at /Users/nathan.daly/.julia/packages/Atom/cR6bU/src/repl.jl:135
   [11] (::getfield(Atom, Symbol("##168#170")){Module})() at /Users/nathan.daly/.julia/packages/Atom/cR6bU/src/repl.jl:157
   [12] with_logstate(::getfield(Atom, Symbol("##168#170")){Module}, ::Base.CoreLogging.LogState) at ./logging.jl:395
   [13] with_logger at ./logging.jl:491 [inlined]
   [14] evalrepl(::Module, ::String) at /Users/nathan.daly/.julia/packages/Atom/cR6bU/src/repl.jl:148
   [15] top-level scope at /Users/nathan.daly/.julia/packages/Atom/cR6bU/src/repl.jl:190
   [16] eval(::Module, ::Any) at ./boot.jl:330
   [17] eval_user_input(::Any, ::REPL.REPLBackend) at /Users/nathan.daly/builds/julia-1.3/usr/share/julia/stdlib/v1.3/REPL/src/REPL.jl:86
   [18] macro expansion at /Users/nathan.daly/builds/julia-1.3/usr/share/julia/stdlib/v1.3/REPL/src/REPL.jl:118 [inlined]
   [19] (::getfield(REPL, Symbol("##26#27")){REPL.REPLBackend})() at ./task.jl:270
  
ERROR: There was an error during testing

That seems to fail about 1/5 times I run it.

Metadata

Metadata

Assignees

Labels

bugIndicates an unexpected problem or unintended behaviormultithreadingBase.Threads and related functionality

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions