¿Cómo detectar excepciones en concurrent.futures en Python3?

Acabo de pasar a python3 como resultado de su módulo de futuros concurrentes. Me preguntaba si podría hacer que detectara errores. Quiero usar futuros concurrentes para el progtwig paralelo, si hay módulos más eficientes, por favor hágamelo saber.

No me gusta el multiprocesamiento ya que es demasiado complicado y no hay mucha documentación disponible. Sería genial, sin embargo, si alguien pudiera escribir un Hello World sin clases, las funciones solo usarían el multiprocesamiento para el procesamiento en paralelo para que sea fácil de entender.

Aquí hay un script simple:

from concurrent.futures import ThreadPoolExecutor def pri(): print("Hello World!!!") def start(): try: while True: pri() except KeyBoardInterrupt: print("YOU PRESSED CTRL+C") with ThreadPoolExecutor(max_workers=3) as exe: exe.submit(start) 

El código anterior era solo una demostración, de cómo CTRL + C no funcionará para imprimir el archivo.

Lo que quiero es poder llamar a una función si hay un error presente. Esta detección de errores debe ser de la propia función.

Otro ejemplo

 import socket from concurrent.futures import ThreadPoolExecutor s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) def con(): try: s.connect((x,y)) main() except: socket.gaierror err() def err(): time.sleep(1) con() def main(): s.send("[+] Hello") with ThreadPoolExecutor as exe: exe.submit(con) 

Aquí hay una solución. No estoy seguro de que te guste, pero no puedo pensar en ningún otro. He modificado tu código para que funcione.

 from concurrent.futures import ThreadPoolExecutor import time quit = False def pri(): print("Hello World!!!") def start(): while quit is not True: time.sleep(1) pri() try: pool = ThreadPoolExecutor(max_workers=3) pool.submit(start) while quit is not True: print("hei") time.sleep(1) except KeyboardInterrupt: quit = True 

Aquí están los puntos:

  1. Cuando se utiliza with ThreadPoolExecutor(max_workers=3) as exe , espera hasta que se hayan realizado todas las tareas. Echa un vistazo a Doc

    Si la wait es Verdadero, este método no volverá hasta que todos los futuros pendientes se hayan ejecutado y los recursos asociados con el ejecutor hayan sido liberados. Si la espera es False , este método regresará de inmediato y los recursos asociados con el ejecutor se liberarán cuando todos los futuros pendientes se ejecuten. Independientemente del valor de espera, el progtwig completo de Python no se cerrará hasta que se ejecuten todos los futuros pendientes.

    Puede evitar tener que llamar a este método explícitamente si usa la instrucción with , que cerrará el Executor (esperando como si se hubiera llamado a Executor.shutdown() con la espera establecida en True )

    Es como llamar a join() en un hilo.
    Es por eso que lo reemplacé con:

     pool = ThreadPoolExecutor(max_workers=3) pool.submit(start) 
  2. El hilo principal debe estar haciendo “trabajo” para poder atrapar un Ctrl + C. Así que no puedes simplemente dejar el hilo principal allí y salir, la forma más sencilla es ejecutar un bucle infinito

  3. Ahora que tiene un bucle ejecutándose en el subproceso principal, cuando presione CTRL+C , el progtwig ingresará en el bloque except KeyboardInterrupt y establecerá quit=True . Entonces su hilo de trabajador puede salir.

Estrictamente hablando, esto es sólo una solución. Me parece que es imposible tener otra manera para esto.

Editar
No estoy seguro de lo que te está molestando, pero puedes encontrar una excepción en otro hilo sin problema:

 import socket import time from concurrent.futures import ThreadPoolExecutor s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) def con(): try: raise socket.gaierror main() except socket.gaierror: print("gaierror occurred") err() def err(): print("err invoked") time.sleep(1) con() def main(): s.send("[+] Hello") with ThreadPoolExecutor(3) as exe: exe.submit(con) 

Salida

 gaierror occurred err invoked gaierror occurred err invoked gaierror occurred err invoked gaierror occurred ...