Julia @REPL中的spawn和@async行为
我已经通读了Julia @REPL中的spawn和@async行为,julia,Julia,我已经通读了@async和@spawn,但没有显示: function f1(j) for i=1:j println(i*j) end end function f2(j) for i=1:j @spawn println(i*j) end end 运行时,始终跳过第二个值,包括@async和@spawn julia> f1(5) 5 10 15 20 25 julia> f2(5) 5 julia> 15
@async
和@spawn
,但没有显示:
function f1(j)
for i=1:j
println(i*j)
end
end
function f2(j)
for i=1:j
@spawn println(i*j)
end
end
运行时,始终跳过第二个值,包括@async
和@spawn
julia> f1(5)
5
10
15
20
25
julia> f2(5)
5
julia>
15
20
25
它似乎对将数据输出到数组中没有影响(…或者是否有影响?),执行@sync f2(5)
会恢复该行为。主要是想知道为什么会发生这种情况,为什么会出现第二个值
编辑:
它在两个系统上的作用如下:
julia> versioninfo()
Julia Version 0.4.0-dev+4850
Commit c260ea9* (2015-05-15 15:14 UTC)
Platform Info:
System: Darwin (x86_64-apple-darwin13.4.0)
CPU: Intel(R) Core(TM) i5-2415M CPU @ 2.30GHz
WORD_SIZE: 64
BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Sandybridge)
LAPACK: libopenblas
LIBM: libopenlibm
LLVM: libLLVM-3.3
julia> versioninfo()
Julia Version 0.4.0-dev+4888
Commit ca2ca31* (2015-05-18 15:20 UTC)
Platform Info:
System: Linux (x86_64-linux-gnu)
CPU: AMD FX(tm)-8120 Eight-Core Processor
WORD_SIZE: 64
BLAS: libopenblas (NO_LAPACK NO_LAPACKE DYNAMIC_ARCH NO_AFFINITY Bulldozer)
LAPACK: liblapack.so.3
LIBM: libopenlibm
LLVM: libLLVM-3.3
如果我每晚使用0.4,我也可以重现问题:
_
_ _ _(_)_ | A fresh approach to technical computing
(_) | (_) (_) | Documentation: http://docs.julialang.org
_ _ _| |_ __ _ | Type "help()" for help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 0.4.0-dev+5032 (2015-05-27 06:04 UTC)
_/ |\__'_|_|_|\__'_| | Commit bae38c2* (0 days old master)
|__/ | x86_64-apple-darwin13.4.0
julia> function f2(j)
for i=1:j
@spawn println(i*j)
end
end
f2 (generic function with 1 method)
julia> f2(5)
5
julia>
15
20
25
版本0.3倾向于选择一个不同的时间,该时间不会对终端图纸产生破坏性竞争:
julia> f2(5)
510152025
julia>
(这里,每个println作为缓冲打印和与其他任务交错的换行打印处理。)
0.4 nightly的输出看起来不完整的原因是计时方式与终端处理换行的方式相结合,移动到哑终端可以看到10:
$ TERM="dumb" ./julia-4
_
_ _ _(_)_ | A fresh approach to technical computing
(_) | (_) (_) | Documentation: http://docs.julialang.org
_ _ _| |_ __ _ | Type "help()" for help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 0.4.0-dev+5032 (2015-05-27 06:04 UTC)
_/ |\__'_|_|_|\__'_| | Commit bae38c2* (0 days old master)
|__/ | x86_64-apple-darwin13.4.0
WARNING: Terminal not fully functional
julia> function f2(j)
for i=1:j
@spawn println(i*j)
end
end
f2 (generic function with 1 method)
julia> f2(5)
5
julia> 10
15
20
25
一般来说,您可以指望通过@spawn
或@async
请求执行的任何处理,但您无法指望任何共享资源的竞争会如何进行。共享终端的这种情况就是一个例子。任何由异步/衍生进程构建的共享数据结构都可以通过以任意顺序运行的计算以及交互修改等方式构建
主任务处理组织其他任务输出的示例如下所示:
function f3(j)
x = Any[@spawn i*j for i=1:j]
for i in x
println(fetch(i))
end
end
当然,如果将
i*j
替换为CPU使用率高的函数和/或比写入单个输出文件或TTY的瓶颈更重要的等待i/O的原因,那么这只会很好地执行,以弥补移动数据的成本。这不是我得到的行为在linux上(我得到所有的数字,后面是换行符)。我想说,输出差距很可能是终端如何处理系统上的换行符的问题。也许可以添加versioninfo(),以便具有相同系统的人可以复制它,或者尝试将术语设置为“dumb”查看行为是否会随着终端支持的减少而改变。好的,我添加了versioninfo()
输出,并尝试将其设置为“dumb”(不会认为它是我的终端)。感谢您的解释。所有这些都不会影响终端外的数据,例如,编写输出(使用@spawn
)到文件?我只使用了夜间版本。希望确保这不是一个错误。@snd,因为0.3行为是有效的(println是非原子的)如果不使用某种形式的同步,您就无法在任务之间真正共享可写文件。对于一般的多任务处理,您必须仔细查看有哪些保证,或者使用同步原语,或者让一个任务负责需要特定顺序的任何事情。我将添加一个使主任务负责的示例。谢谢。您的e示例真的有助于我的理解/学习。”…你必须仔细看看有什么保证…“谢谢你也这么做。我不知道问这个问题可能会让我在将来避免一些头痛……因为我根本没有仔细看这个问题。