Parallel processing 在Julia中停止@spawned任务
我遇到了以下情况:库中的算法使用了一些随机性,通常非常快,但有时会卡住(这对于SAT解算器来说很常见,例如) 我想做以下几点:启动任务的多个实例,并保持第一个实例成功的结果,杀死其他实例。在伪代码中:Parallel processing 在Julia中停止@spawned任务,parallel-processing,task,julia,Parallel Processing,Task,Julia,我遇到了以下情况:库中的算法使用了一些随机性,通常非常快,但有时会卡住(这对于SAT解算器来说很常见,例如) 我想做以下几点:启动任务的多个实例,并保持第一个实例成功的结果,杀死其他实例。在伪代码中: futures = [@spawn myfunction(mydata)] while true i = findnext(isready, futures) if i != nothing result = fetch(i) foreach(kil
futures = [@spawn myfunction(mydata)]
while true
i = findnext(isready, futures)
if i != nothing
result = fetch(i)
foreach(kill_task, futures)
break
end
sleep(0.1)
end
但我找不到像“杀戮任务”这样的东西Distributed.delu客户端
听起来是个不错的选择,但似乎没有做到这一点
作为奖励,最好避免投票(睡觉等)
请注意,修改“myfunction”以要求其自行终止是不可接受的,它必须被终止(因为它位于外部库中)。下面是一个完整的代码,它生成多个工作进程,从较早完成的进程中获取结果,一旦收到结果,所有工作进程都将终止。 我认为这段代码对于科学计算的许多场景非常有用:
using Distributed
addprocs(4)
@everywhere using Distributed
@everywhere function getSomething()
tt = rand(1:20)
println("working for $tt seconds")
for i in 1:tt
sleep(1.0)
end
println("Finally, I am ready")
return 100+myid()
end
function getFirst(workerf::Function, ws_list::Vector{Int}=workers())
res = Vector{Union{Future,Nothing}}(nothing,length(ws_list))
for i in 1:length(ws_list)
@async begin
res[i] = @spawnat ws_list[i] workerf()
end
end
my_res = nothing
while true
for i in 1:length(ws_list)
if res[i]!=nothing && isready(res[i])
my_res = fetch(res[i])
println(ws_list[i]," is ready!")
break
else
println(ws_list[i]," NOT ready!")
end
end
if my_res != nothing
@sync for i in 1:length(ws_list)
@async interrupt(ws_list[i])
end
break
end
sleep(0.5)
end
println(my_res)
return my_res
end
现在让我们来旋转一下:
julia> value = getFirst(getSomething);
2 NOT ready!
From worker 4: working for 16 seconds
From worker 2: working for 19 seconds
From worker 5: working for 2 seconds
3 NOT ready!
From worker 3: working for 15 seconds
4 NOT ready!
5 NOT ready!
2 NOT ready!
3 NOT ready!
4 NOT ready!
5 NOT ready!
2 NOT ready!
3 NOT ready!
4 NOT ready!
5 NOT ready!
2 NOT ready!
3 NOT ready!
4 NOT ready!
5 NOT ready!
From worker 5: Finally, I am ready
2 NOT ready!
3 NOT ready!
4 NOT ready!
5 is ready!
Worker 3 terminated.
Worker 2 terminated.
Worker 5 terminated.
Worker 4 terminated.
让我们看看结果:
julia> println(value)
105
好的,我的第一个问题的部分答案是:“isready”表示未来是否已经准备好了产出。非常感谢!但是,如果另一个工作进程在interrupt()调用之前完成,则似乎存在竞争条件:在这种情况下,整个Julia内核在该工作进程上被杀死。
interrupt
的文档中显示“中断指定工作进程上当前正在执行的任务。这相当于在本地机器上按Ctrl-C”。通常,在许多情况下,在REPL上按Ctrl-C会以一种丑陋的方式杀死Julia kernell进程。因此,我要说的是,一旦您对一个工作进程调用中断,一个进程可能会死,也可能不会死——您可能需要检查它们的状态。