我有一个问题,我想并行执行许多彼此独立的语句。
我已经阅读了很多示例,这些示例表明此玩具示例应该可以工作:
function f1(x,y,z)
@sync @async begin
# these two statements can be computed independently
v1 = x+y;
v2 = y+z;
end
return v1*v2
end
但是,由于我收到以下错误,看来@sync部分没有等待结果完成:
y1 = f1(1,2,3);
ERROR: LoadError: UndefVarError: v1 not defined
我成功地使它像这样工作:
function f2(x,y,z)
v1 = @async x+y;
v2 = @async y+z;
return wait(v1)*wait(v2)
end
但是,在我所看到的许多示例中,如果使用@sync块,则wait语句似乎是不必要的。
我正在使用Julia 0.6.2。
任何帮助将不胜感激。
答案 0 :(得分:7)
原因是@async
围绕传递给它的表达式创建了一个闭包。您可以通过运行以下命令来查看它:
julia> @macroexpand @async begin
v1 = x+y;
v2 = y+z;
end
:((Base.async_run_thunk)((()->begin # task.jl, line 335:
begin # REPL[22], line 2:
v1 = x + y # REPL[22], line 3:
v2 = y + z
end
end)))
这意味着v1
和v2
变量在闭包外部将不可见,除非它们存在于封闭函数范围内。
要解决此问题,您可以在local v1, v2
的开头添加f1
语句:
julia> function f1(x,y,z)
local v1, v2
@sync @async begin
v1 = x+y;
v2 = y+z;
end
return v1*v2
end
f1 (generic function with 1 method)
julia> f1(1,2,3)
15
并且您会看到所有工作都按预期进行。
另外,如果封闭范围不是函数而是全局范围,则必须使用global
关键字来获取所需的内容:
julia> x,y,z = 1,2,3
(1, 2, 3)
julia> @sync @async begin
global v1 = x+y;
global v2 = y+z;
end
Task (done) @0x0000000018be30f0
julia> v1*v2
15