как убить задание у Юлии? - PullRequest
       7

как убить задание у Юлии?

0 голосов
/ 25 августа 2018

У меня есть код Джулии, где мне нужно выполнить две операции параллельно. Моя проблема в том, что мне нужно остановить и убить одну операцию, если она занимает слишком много времени.

Я пытался с Task, но теперь не могу найти способ убить задачу. Мой код:

function mytask(myargs, ch)
    # do some work (optimize a problem with Gurobi)
    # that can go on for a very long time
    put!(ch, computationResult)
end

ch = Channel(1)
task = @async mytask(args, ch)

# now the main task does some other work
# and at the end

if isready(ch)
    taskResult = take!(ch)
else
    # the result of th async task became useless
    # so here I need to kill the async task
end

# continue the execution

Я нашел этот похожий старый вопрос , но я думаю, что решение больше не поддерживается, потому что я не могу найти метод throwto в документации, и я также попробовал его, но я получаю это сообщение об ошибке

WARNING: Workqueue inconsistency detected: shift!(Workqueue).state != :queued
ERROR (unhandled task failure): InterruptException:

Меня не заставляют использовать задачи, я могу использовать процессы потоков или любое другое решение, пока оно работает

1 Ответ

0 голосов
/ 26 августа 2018

Вы написали, что, ожидая завершения длинных вычислений, вам нужно выполнить какую-то другую обработку на переднем плане.@async предоставляет только механизм «зеленой нити» и, следовательно, не подходит для вашей проблемы - ваша программа все равно сможет использовать только один Thread за раз.Кроме того, в настоящее время в заданиях Julia не поддерживается механизм убийства (если вы сами не делаете это каким-то образом программно).

Чистым решением является использование механизма Julia Distributed.Ниже приведен пример кода.

Код запускает длительные вычисления - в зависимости от того, завершится ли вычисление в заявленное время результатами или собранными, или процесс будет остановлен.

Наслаждайтесь!

using Distributed

Distributed.addprocs(1)  #we add one worker process that will be the 
                         #long-running background computation
wid = workers()[end]     #take last worker (there is just one anyway)
const result = RemoteChannel(()->Channel{Tuple}(1));
@everywhere function longrun(result,c=3,time=0)
    #write whatever code you need here
    for i in 1:c
        sleep(time)
        println("Working $i at $(myid())")
    end
    #we use the RemoteChannel to collect the result
    put!(result, (c,time,999999, myid()))
end

function ready_or_not(result,wid)
    if !isready(result)
        println("Computation at $wid will be terminated")
        rmprocs(wid)
        return nothing
    else
        return take!(result)
    end
end


remote_do(longrun,wid,result) #this takes far less than a second...
sleep(1)
show(ready_or_not(result,wid)) # .. and you should see the result

remote_do(longrun,wid,result,10,3) #this takes 30s
sleep(7)
show(ready_or_not(result,wid)) #ready_or_not() terminates the worker process

Надеюсь, это поможет.

...