-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

El 01/11/11 18:57, Jose Caballero escribió:

> tengo un programita que crea varios threads.
> Necesito ser capaz de lanzar excepciones dentro de cada uno de ellos si
> algo no va bien, y propagar esas excepciones hasta el hilo principal.
> Estoy leyendo sobre el tema en google, y estoy un poco confundido.
> Parece que la captura de excepciones generadas en un hilo 'hijo' no es
> facil.
> Google parece ofrecer multitud de opciones, pero me preguntaba si
> alguien en la lista ha tenido antes el mismo problema y puede ofrecer
> una solucion sencilla, que funcione con python2.4.
> Existe una solucion que sea mas o menos estandar?

La estrategia que se me ocurre es que el hilo principal esté comprobando
si algún hilo le ha dejado un aviso de que algo ha ido mal. Para ello,
bastaría con usar una queue. Algo así, para hacerte una idea:

!/usr/bin/env python
#-*- coding: utf8 -*-

import sys
import threading
import Queue

class ExThread(threading.Thread):

    def __init__(self, bucket):
        threading.Thread.__init__(self)
        self.bucket=bucket

        #patching run method
        self._run, self.run = self.run, self._run_ex

    def _run_ex(self):

        try:
            self._run()
        except:
            self.bucket.put(sys.exc_info())

class MyThread(ExThread):

    def run(self):
        #raise an exception
        print 1/0

def main():
    bucket = Queue.Queue()

    t = MyThread(bucket)
    t.start()

    while True:
        t.join(0.1) #Esperar un poco en cada iteración
        try:
            exc = bucket.get(block=False)
        except Queue.Empty:
            pass
        else:
            print "Capturada excepción: %s"%exc[1]

        if not t.isAlive():
            break

if __name__ == '__main__':
    main()



Si quieres algo más controlable, prueba a usar corrutinas síncronas con
gevent (http://www.gevent.org), algo así:

import gevent

def main(arg):
    return 1/arg

jobs=[gevent.spawn(main,i) for i in range(3)]

gevent.joinall(jobs, raise_error=False)

for j in jobs:
    try:
        res=j.get()
        print "Resultado:",res
    except:
        print "Excepción capturada:",j.exception



También se podría implementar algo usando el "modelo actor" con la
librería "pykka" (http://jodal.github.com/pykka/), pero requiere una
versión de python superior a la 2.4 (Con jython, se podría usar
directamente la librería "akka" para jvm).


- -- 
Hyperreals *R: http://ch3m4.org/blog
Quarks, bits y otras criaturas infinitesimales
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJOsMLjAAoJEFdWyBWwhL4FHrAH/2mWmavitN8RPUBcN4yZFKRG
2ujIygzhzMypZYH0gyFNy0864z5WUbZwXe2fHC8g+VLa4idrzuFfrqB6+h4Q2FEk
xPniUZ0MmYA9c7JFK/zXNYnrjD9ynODKKN+XxO0PVLpwf8ZZ4YagtIGE/Qqd012r
av92qyS5dog45Ca6Wh21eOt7zznbG7ZaacAU2dl9hkunS4J8OVkWd7JKYaUoUwLr
WCTm+KlR7US24s7Osc+Xionkw6t0/iEU3sjeJg7gUkgikqRcgovFtMvoZL/8LmII
mmdAVl8BYCnOLfWa5bx+mASgRbDME7NRoYVOv0bYmKist9Ty5WxNr4NM1RdbGCw=
=+bi5
-----END PGP SIGNATURE-----
_______________________________________________
Python-es mailing list
Python-es@python.org
http://mail.python.org/mailman/listinfo/python-es
FAQ: http://python-es-faq.wikidot.com/

Responder a