我在julia中遇到了一个奇怪的bug。基本上,在合适的地方添加一个print("")语句会以一种积极的方式改变以下代码的行为。我感到非常困惑。为什么?
xs = [1,2,3,4,5,6,7,8]
cmds = [`sleep $x` for x in xs]
f = open("results.txt", "w")
i = 1
nb_cmds = length(cmds)
max_running_ps = 3
nb_running_ps = 0
ps = Dict()
while true
# launching new processes if possible
if nb_running_ps < max_running_ps
if i <= nb_cmds && !(i in keys(ps))
print("spawn:")
println(i)
p = spawn(cmds[i], Base.DevNull, f, f)
setindex!(ps,p,i)
nb_running_ps = nb_running_ps + 1
i = i+1
end
end
# detecting finished processes to be able to launch new ones
for j in keys(ps)
if process_exited(ps[j])
print("endof:")
println(j)
delete!(ps,j)
nb_running_ps = nb_running_ps - 1
else
print("")
# why do I need that ????
end
end
# nothing runs and there is nothing to run
if nb_running_ps <= 0 && i > nb_cmds
break
end
end
close(f)
println("finished")
实际上,命令比sleep更有用。
如果删除或注释print(""),条件语句"if process_exited(ps[j])"的内容似乎永远不会运行,即使前max_running_ps个进程已经完成,程序仍会陷入无限循环。
一些背景:我需要运行一段代码,这段代码需要很长时间才能运行(并且使用大量内存),针对一组参数(在此处由x表示)的不同值进行运行。由于它们需要很长时间,我想要并行运行它们。另一方面,不同的运行之间几乎没有共享内容,因此通常的并行工具并不真正相关。最后,我想避免简单的pmap,首先是为了避免如果出现故障就失去所有内容,其次是因为在运行过程中获得部分结果可能是有用的。因此,我使用julia编写了这段代码(因为实际计算的主要代码是用julia编写的)。
print
是异步的(出于性能原因)并且会产生 yield。也许可以尝试使用@sync print("")
代替?如果这样解决了你的问题,那么我会将其发布为答案。 - Fengyang Wang