我找不到有关@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
宏创建的任务中发生任务切换的位置。
如何查看代码中发生任务切换的点?
答案 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是教科书的例子为什么绿色线程首先是有用的。)