【问题标题】:Is it possible to implement effect handlers using Julia's coroutines?是否可以使用 Julia 的协程来实现效果处理程序?
【发布时间】:2021-11-22 07:27:31
【问题描述】:

我对 Julia、协程和 effect handlers 都是新手,所以我要问的问题可能会被误导,但是是否可以使用协程实现效果处理程序?我认为 Scheme 的协程将允许您获取计算块的其余部分以供以后恢复,这将允许实现效果处理程序,但 Julia 的协程似乎没有该功能。这是错误的,还是像我链接到的库那样进行 CPS 转换并以此为基础的 EH 实现的唯一选择?

【问题讨论】:

    标签: julia coroutine


    【解决方案1】:

    关于您的问题,我有很多不知道的地方,但在 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

    【讨论】:

    • 与我的问题无关。您可能会感兴趣观看一些 effect handler 视频以了解它们是什么。
    猜你喜欢
    • 2011-03-27
    • 1970-01-01
    • 1970-01-01
    • 2010-11-09
    • 2011-01-15
    • 2015-09-29
    • 2015-09-05
    • 1970-01-01
    • 2012-03-21
    相关资源
    最近更新 更多