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")
(事实上,这些命令实际上比睡眠更有用。)
如果删除或评论了打印(&#34;&#34;),条件&#34; if process_exited(ps [j])&#34;的内容似乎永远不会运行,即使第一个max_running_ps进程已经完成,程序也会进入无限循环。
一些背景知识:我需要运行一段代码,这段代码需要很长时间才能运行(并使用大量内存),用于一组参数的不同值(此处用x表示)。由于他们需要很长时间,我想并行运行它们。另一方面,不同的运行之间几乎没有任何共享,因此通常的并行工具并不真正相关。最后,我想避免使用简单的pmap,首先是为了避免在出现故障时丢失所有内容,其次是因为在运行期间获得部分结果可能很有用。因此这段代码(用julia编写,因为实际计算的主代码是在julia中)。
答案 0 :(得分:4)
这不是一个错误,但如果您不习惯这种异步编程,可能会感到惊讶。
Julia默认是单线程的,一次只能运行一个任务。为了完成任务,Julia需要切换到它。只要当前任务产生,就会切换任务。
print
也是一个异步操作,所以它会让你屈服,但更简单的方法是yield()
,它可以实现相同的结果。有关异步编程的更多信息,请参阅the documentation。