Python: concurrent.futures Como torná-lo cancelável?
Python concurrent.futures e ProcessPoolExecutor fornecem uma interface elegante para agendar e monitorar tarefas. Futuros aindaprovidenciar um método .cancel ():
cancelar(): Tenta cancelar a chamada. Se a chamada forsendo executado no momento e não pode ser cancelado o método retornará False, caso contrário, a chamada será cancelada e o método retornará True.
Infelizmente de forma semelhantePergunta, questão (referente ao assíncio), a resposta afirma que as tarefas em execução não são permitidas usando esse trecho da documentação, mas os documentos não dizem isso, apenas se eles estiverem executando AND uncancelable.
O envio de multiprocessamento.Eventos para os processos também não é trivialmente possível (isso é feito através de parâmetros como no multiprocesso.Processo retorna um RuntimeError)
O que estou tentando fazer? Gostaria de particionar um espaço de pesquisa e executar uma tarefa para cada partição. Mas basta ter UMA solução e o processo exige muita CPU. Portanto, existe uma maneira realmente confortável de fazer isso que não compense os ganhos usando o ProcessPool para começar?
Exemplo:
from concurrent.futures import ProcessPoolExecutor, FIRST_COMPLETED, wait
# function that profits from partitioned search space
def m_run(partition):
for elem in partition:
if elem == 135135515:
return elem
return False
futures = []
# used to create the partitions
steps = 100000000
with ProcessPoolExecutor(max_workers=4) as pool:
for i in range(4):
# run 4 tasks with a partition, but only *one* solution is needed
partition = range(i*steps,(i+1)*steps)
futures.append(pool.submit(m_run, partition))
done, not_done = wait(futures, return_when=FIRST_COMPLETED)
for d in done:
print(d.result())
print("---")
for d in not_done:
# will return false for Cancel and Result for all futures
print("Cancel: "+str(d.cancel()))
print("Result: "+str(d.result()))