朱莉娅:了解任务切换何时发生

时间:2014-07-27 00:00:52

标签: asynchronous julia

我找不到有关@async宏的详细文档。从关于并行性的文档中我了解到,在Julia进程中只有一个系统线程,并且在yieldto函数的帮助下有明确的任务切换 - 如果我错了,请纠正我。

对我来说,很难理解这些任务切换何时只是通过查看代码来实现,并且知道它何时发生似乎至关重要。

据我所知,代码中的某个地方(或代码调用的某个函数)中的yieldto需要确保系统不会只停留在一个任务中。

例如,当有read次操作时,在读取内部可能会有wait次调用,并且在wait的实现中可能会有yieldto次调用。我认为如果没有yieldto调用,代码就会卡在一个任务中;但是运行以下示例似乎证明了这个假设是错误的。

@async begin # Task A
    while true
        println("A")
    end    
end

while true # Task B
  println("B")
end

此代码生成以下输出

BA
BA
BA
...

我很不清楚在上面代码中由@async宏创建的任务中发生任务切换的位置。

如何查看代码中发生任务切换的点?

1 个答案:

答案 0 :(得分:5)

任务切换发生在println("A")的调用中,在某些时候调用write(STDOUT, "A".data)。因为isa(STDOUT, Base.AsyncStream)并且没有更专业的方法,所以这解析为:

write{T}(s::AsyncStream,a::Array{T}) at stream.jl:782

如果你看一下这种方法,你会发现它在当前任务stream_wait(ct)上调用ct,然后调用wait()

(另请注意println不是原子的,因为在写参数和换行符之间存在潜在的wait。)

当然,您可以通过查看所有所涉及的代码来确定何时发生类似的事情。但我不明白为什么你需要确切地知道这一点,因为在使用并行性时,你不应该依赖进程而不是切换上下文。如果您依赖某个执行顺序,请明确同步。

(你已经在你的问题中注意到了这一点,但是让我在这里重申一下:根据经验,当使用绿色线程时,你可以在进行IO时期望潜在的上下文切换,因为阻塞IO是教科书的例子为什么绿色线程首先是有用的。)