我正在尝试了解如何以正确的方式在宏中使用 RemoteChannel。在函数或 REPL 中,以下代码有效:
addprocs(3)
r = RemoteChannel(3)
@spawnat(3,put!(r,10))
fetch(r) # Gives 10
但是,如果我将相同的内容放入宏中:
macro rrtest(src,val)
quote
r = RemoteChannel($(esc(src)))
@spawnat($(esc(src)), put!(r, $(esc(val))))
println(fetch(r))
end
end
然后用相同的参数调用它
@rrtest(3,10)
然后 REPL 就停止了。像这样使用 RemoteChannels 有什么问题吗?
最佳答案
macro rrtest(src,val)
quote
r = RemoteChannel($(esc(src))) #Using a `Future` here maybe be better
remotecall_wait(r_i->put!(r_i, $(esc(val))), $(esc(src)), r)
wait(r);
println(fetch(r))
end
end
wait(r)
应该 是必需的 -- fetch
应该在使用时调用 wait
Future
或 RemoteChannel
。
但有时似乎确实如此。
将 @spawnat
更改为 remotecall
意味着您可以传入 r
,没有它,它就会获取。我认为宏卫生如何与闭包嵌套是有问题的,闭包是用宏创建的。 (@spawnat
) 在另一个宏中创建闭包。推理是尴尬的。
总的来说,我发现 @spawnat
比 remote_call
更难推理。
它需要remotecall_wait
的原因是,否则,何时其内容将运行。这意味着发生在 r
上的事情本身并不清楚。感觉应该是安全的,但好像不是。
我认为因为等待 r
,而不是等待设置 r
的 remotecall
永远不能确定允许 remotecall
运行。
总结:
- 更喜欢
remotecall
而不是@spawnat
,尤其是在宏中,这样更容易推理。 - 有时您必须
等待
才能获取
它们。这可能是一个错误 - 有时等待 X,当 X 由
remotecall
(或@spawnat
)返回 future Y 时,需要先等待 Y。也可能是一个错误
关于parallel-processing - 宏中的 RemoteChannel 正在停滞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39802864/