【问题标题】:Stopping @spawn-ed tasks in Julia在 Julia 中停止 @spawn-ed 任务
【发布时间】:2019-08-20 08:28:56
【问题描述】:

我处于以下情况:库中的算法使用一些随机性,并且通常非常快但有时会卡住(例如,这对于 SAT 求解器很常见)。

我想做以下事情:启动任务的许多实例,并保持第一个成功的结果,杀死其他的。在 Julia 伪代码中:

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

但我找不到像“kill_task”这样的东西; Distributed.del_client 听起来很有可能,但似乎没有这样做。

作为奖励,最好避免轮询(睡觉等)

请注意,修改“myfunction”要求它自己死是不可接受的,它必须被杀死(因为它在外部库中)。

【问题讨论】:

  • 好的,我的第一个问题的部分答案:“isready”表示未来是否准备好输出。

标签: parallel-processing task julia


【解决方案1】:

这是一个完整的代码,它产生了几个工作进程,从较早完成的那个中获取结果,一旦收到结果,所有工作进程都会被终止。 我觉得这段代码对很多场景都很有用,就是科学计算:

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

【讨论】:

  • 非常感谢!但是,如果另一个工作人员在调用 interrupt() 之前完成,则似乎存在竞争条件:在这种情况下,整个 Julia 内核都会在该工作人员上被杀死。
  • interrupt 的文档中写着“在指定的worker上中断当前正在执行的任务。这相当于在本地机器上按Ctrl-C”。通常,在很多情况下,按Ctrl REPL 上的 -C 会以一种丑陋的方式杀死 Julia kernell 进程。因此,我会说,一旦你在工作人员上调用中断,一个进程可能会死或不死 - 你可能想检查它们的状态。
猜你喜欢
  • 2017-02-01
  • 2015-01-28
  • 1970-01-01
  • 2013-12-01
  • 2011-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-01
相关资源
最近更新 更多