【问题标题】:Julia: Passing data between coroutines (tasks)Julia:在协程(任务)之间传递数据
【发布时间】:2014-04-22 01:15:19
【问题描述】:

我曾尝试让两个任务(协程)合作,但无济于事。下面是我所拥有的。我从来没有看到来自源函数或接收器函数的 printlns,并且 wait() 调用似乎永远挂起。我还尝试将 p (源)任务作为全局变量,而不是将其作为参数传递给 sink(),但这似乎也不起作用(即使我在 sinke() 中将其声明为全局变量。

这是我发现我可以在 Go 中使用通道和 goroutine 轻松完成的事情。

我也尝试过在 source() 和 sink() 函数中调用 yieldto(),但我似乎仍然以死锁告终。

谁有多个任务以任何方式共享数据的例子?理想情况下,我会有一个管道或一长串任务。

提前感谢您的帮助。

println("Hello")

function source()
  println("source start")
  produce("start")
  produce("stop")
end

function sink(p::Task)
  println("sink start")
  println(consume(p))
  println(consume(p))
end


a = Task( source )
b = Task( () -> sink(a)   )

wait(b)
wait(a)

println("Goodbye")

【问题讨论】:

    标签: task coroutine julia


    【解决方案1】:

    在 Julia 中,创建任务不会自动安排该任务。等待功能也没有安排,因此您最终会陷入死锁。这与 Go 有很大的不同,Go 语句为您处理所有调度。在朱莉娅你必须做更多的工作。具体使用@sync 和@async 宏来制作 更容易。

    @sync begin # @sync will wait for all the contained tasks to terminate.
       a = @async source() # @async will create and schedule a task for you automatically
       @async sink(a)
     end
    

    您会注意到这也不会终止。所有的打印都会发生,但任务不会终止。原因是 @sync 等待任务 a 完成,但任务 a 尚未安排。将最终消耗或计划添加到您的接收器函数以强制任务 a 最后一次被安排,以便它可以终止。或者更好的是在任务上使用 for 循环,这样你总是会耗尽它。

    println("Hello")
    
    function source()
      println("source start")
      produce("start")
      produce("stop")
      println("source end")
    end
    
    function sink(p::Task)
      println("sink start")
      for s in p
        println(s)
      end
      println("sink end")
    end
    
    @sync begin
       a = @async source()
       @async sink(a)
     end
    
    println("Goodbye")
    

    Julia 的任务是合作安排的,这基本上意味着您必须确保每个任务都由您自己安排。运行时不会为你做这件事。幸运的是,@sync 和 @async 宏为您完成了大部分工作。

    【讨论】:

    • 太棒了!感谢您的明确答复。我可以看到 julia 对协程提供了更细粒度的控制。感谢您的帮助。
    猜你喜欢
    • 2017-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-21
    • 1970-01-01
    • 2015-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多