宏中的 RemoteChannel 正在停滞

RemoteChannel in a Macro is Stalling

我正在尝试了解如何以正确的方式在宏中使用 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) 应该 而不是 -- fetchFuture 上使用时应该调用 waitRemoteChannel。 但有时确实如此。

@spawnat 更改为 remotecall 意味着您可以传入 r,没有它,它会得到。我认为宏卫生如何与闭包嵌套是有问题的,闭包是用宏创建的。 (@spawnat) 在另一个宏中创建闭包。推理是尴尬的。 总的来说,我发现 @spawnatremote_call.

更难推理

它需要 remotecall_wait 的原因是,否则当 其内容 运行 时,没有被担保人 。这意味着 r 发生的事情本身还不清楚。感觉应该是安全的,但好像不是。 我认为是因为等待 r,而不是等待设置 rremotecall 永远无法确定允许 remotecall 到 运行.

结论:

  • @spawnat 更喜欢 remotecall,尤其是在宏中,因为这样更容易推理。
  • 有时您必须先 wait 才能 fetch 处理它们。这可能是一个错误
  • 有时会等待 X,当 X 由 remotecall(或 @spawnat)返回未来的 Y 时,需要先等待 Y。也可能是一个错误