una soporta segundo rapida por optimizar optimizacion mas lentas hacer cuantas consultas consulta con como python multithreading concurrent.futures

python - soporta - optimizacion de consultas sql



¿Cómo matas a los futuros una vez que han comenzado? (1)

Es un poco doloroso. Esencialmente, los subprocesos de trabajo se deben finalizar antes de que se pueda salir del subproceso principal. No puedes salir a menos que ellos lo hagan. La solución típica es tener algún estado global, que cada hilo pueda verificar para determinar si deberían hacer más trabajo o no.

Aquí está la quote explicando por qué. En esencia, si los hilos salieran cuando lo hace el intérprete, podrían suceder cosas malas.

Aquí hay un ejemplo de trabajo. Tenga en cuenta que Cc tarda más de 1 segundo en propagarse debido a la duración de la suspensión del subproceso secundario.

#!/usr/bin/env python from __future__ import print_function import concurrent.futures import time import sys quit = False def wait_a_bit(name): while not quit: print("{n} is doing work...".format(n=name)) time.sleep(1) def setup(): executor = concurrent.futures.ThreadPoolExecutor(max_workers=5) future1 = executor.submit(wait_a_bit, "Jack") future2 = executor.submit(wait_a_bit, "Jill") # main thread must be doing "work" to be able to catch a Ctrl+C # http://www.luke.maurits.id.au/blog/post/threads-and-signals-in-python.html while (not (future1.done() and future2.done())): time.sleep(1) if __name__ == "__main__": try: setup() except KeyboardInterrupt: quit = True

Estoy usando el nuevo módulo concurrent.futures (que también tiene un backport de Python 2) para hacer algunas E / S multiproceso simples Estoy teniendo problemas para entender cómo eliminar de forma limpia las tareas que empecé a usar este módulo.

Echa un vistazo a la siguiente secuencia de comandos de Python 2/3, que reproduce el comportamiento que estoy viendo:

#!/usr/bin/env python from __future__ import print_function import concurrent.futures import time def control_c_this(): with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: future1 = executor.submit(wait_a_bit, name="Jack") future2 = executor.submit(wait_a_bit, name="Jill") for future in concurrent.futures.as_completed([future1, future2]): future.result() print("All done!") def wait_a_bit(name): print("{n} is waiting...".format(n=name)) time.sleep(100) if __name__ == "__main__": control_c_this()

Mientras se ejecuta este script, parece imposible eliminar de forma limpia el uso de la interrupción normal del teclado Control-C. Estoy corriendo en OS X.

  • En Python 2.7 tengo que recurrir a kill desde la línea de comandos para matar el script. Control-C es simplemente ignorado.
  • En Python 3.4, Control-C funciona si lo golpeas dos veces, pero luego se descargan muchos rastros extraños de pila.

La mayoría de la documentación que he encontrado en línea habla sobre cómo eliminar de forma limpia los subprocesos con el módulo de threading antiguo. Nada de esto parece aplicarse aquí.

Y todos los métodos provistos dentro del módulo de Future.cancel() concurrent.futures para detener cosas (como Executor.shutdown() y Future.cancel() ) solo funcionan cuando los Futuros aún no han comenzado o están completos, lo cual no tiene sentido en este caso. Quiero interrumpir el futuro inmediatamente.

Mi caso de uso es simple: cuando el usuario pulsa Control-C, la secuencia de comandos debería salir inmediatamente como lo hace cualquier secuencia de comandos de buen comportamiento. Eso es todo lo que quiero.

Entonces, ¿cuál es la forma correcta de obtener este comportamiento al usar concurrent.futures ?