Kal*_*evi 7 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
Run Code Online (Sandbox Code Playgroud)
此代码生成以下输出
BA
BA
BA
...
Run Code Online (Sandbox Code Playgroud)
我很不清楚@async
在上面的代码中由宏创建的任务内部发生任务切换的位置.
如何查看代码中发生任务切换的点?
任务切换发生在调用内部println("A")
,在某些时候调用write(STDOUT, "A".data)
.因为isa(STDOUT, Base.AsyncStream)
并且没有更专业的方法,这解决了:
write{T}(s::AsyncStream,a::Array{T}) at stream.jl:782
Run Code Online (Sandbox Code Playgroud)
如果你看一下这个方法,你会注意到它调用stream_wait(ct)
了当前任务ct
,而当前任务又会调用wait()
.
(另请注意,这println
不是原子的,因为wait
在写入参数和换行符之间存在潜在可能性.)
你当然可以通过查看所涉及的所有代码来确定何时发生类似的事情.但我不明白为什么你需要确切地知道这一点,因为在使用并行性时,你不应该依赖于不切换上下文的进程.如果依赖于某个执行顺序,请明确同步.
(你已经在你的问题中注意到了这一点,但是让我在这里重申一下:根据经验,当使用绿色线程时,你可以在进行IO时期望潜在的上下文切换,因为阻止IO是教科书为什么是绿色的例子线程首先是有用的.)