【发布时间】:2021-11-22 07:27:31
【问题描述】:
我对 Julia、协程和 effect handlers 都是新手,所以我要问的问题可能会被误导,但是是否可以使用协程实现效果处理程序?我认为 Scheme 的协程将允许您获取计算块的其余部分以供以后恢复,这将允许实现效果处理程序,但 Julia 的协程似乎没有该功能。这是错误的,还是像我链接到的库那样进行 CPS 转换并以此为基础的 EH 实现的唯一选择?
【问题讨论】:
我对 Julia、协程和 effect handlers 都是新手,所以我要问的问题可能会被误导,但是是否可以使用协程实现效果处理程序?我认为 Scheme 的协程将允许您获取计算块的其余部分以供以后恢复,这将允许实现效果处理程序,但 Julia 的协程似乎没有该功能。这是错误的,还是像我链接到的库那样进行 CPS 转换并以此为基础的 EH 实现的唯一选择?
【问题讨论】:
关于您的问题,我有很多不知道的地方,但在 Julia 中,实现Task 控制流的“低级”方式是通过Channel。有一个很好的page on this in the manual。当使用大小 0 构建时,通道操作会阻塞,直到删除完成。这是一个例子:
julia> c = Channel{Int}() # specify the type (here `Int`) for better performance, if the type is always the same
Channel{Int64}(0) (empty)
julia> sender(x) = put!(c, x)
sender (generic function with 1 method)
julia> receiver() = println("got ", take!(c))
receiver (generic function with 1 method)
julia> receiver() # this blocked until I hit Ctrl-C
^CERROR: InterruptException:
Stacktrace:
[1] poptask(W::Base.InvasiveLinkedListSynchronized{Task})
@ Base ./task.jl:760
[2] wait()
@ Base ./task.jl:769
[3] wait(c::Base.GenericCondition{ReentrantLock})
@ Base ./condition.jl:106
[4] take_unbuffered(c::Channel{Int64})
@ Base ./channels.jl:405
[5] take!(c::Channel{Int64})
@ Base ./channels.jl:383
[6] receiver()
@ Main ./REPL[3]:1
[7] top-level scope
@ REPL[4]:1
julia> t = @async receiver()
Task (runnable) @0x00007f0b288f4d30
julia> sender(5)
got 5
5
julia> sender(-8) # this blocks because the `receiver` task finished
^CERROR: InterruptException:
Stacktrace:
[1] poptask(W::Base.InvasiveLinkedListSynchronized{Task})
@ Base ./task.jl:760
[2] wait()
@ Base ./task.jl:769
[3] wait(c::Base.GenericCondition{ReentrantLock})
@ Base ./condition.jl:106
[4] put_unbuffered(c::Channel{Int64}, v::Int64)
@ Base ./channels.jl:341
[5] put!(c::Channel{Int64}, v::Int64)
@ Base ./channels.jl:316
[6] sender(x::Int64)
@ Main ./REPL[2]:1
[7] top-level scope
@ REPL[7]:1
julia> t = @async while true receiver() end # run the receiver "forever"
Task (runnable) @0x00007f0b28a4da50
julia> sender(-8)
got -8
-8
julia> sender(11)
got 11
11
在实际应用程序中,您应该确保c 不是非const 全局,请参阅performance tips。
【讨论】: