Python: concurrent.futures ¿Cómo hacer que sea cancelable?
Python concurrent.futures y ProcessPoolExecutor proporcionan una interfaz ordenada para programar y monitorear tareas. Futuros inclusoproporcionar Un método .cancel ():
cancelar(): Intento de cancelar la llamada. Si la llamada esactualmente en ejecución y no se puede cancelar entonces el método devolverá False; de lo contrario, la llamada se cancelará y el método devolverá True.
Desafortunadamente de manera similarpregunta (con respecto a asyncio) la respuesta afirma que las tareas en ejecución no se pueden cancelar usando este recorte de la documentación, pero los documentos no lo dicen, solo si se están ejecutando Y no se pueden cancelar.
Enviar multiprocesamiento.Eventos a los procesos tampoco es trivialmente posible (hacerlo a través de parámetros como en multiproceso. El proceso devuelve un RuntimeError)
¿Qué estoy tratando de hacer? Me gustaría particionar un espacio de búsqueda y ejecutar una tarea para cada partición. Pero es suficiente tener UNA solución y el proceso es intensivo en CPU. Entonces, ¿hay una forma cómoda de lograr esto que no compense las ganancias al usar ProcessPool para empezar?
Ejemplo:
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()))