Threads y concurrencia

Chema Cortes pych3m4 en gmail.com
Jue Ago 2 09:47:27 CEST 2007


El 2/08/07, Jose Gomez-Dans <jgomezdans en gmail.com> escribió:
> Hola,
> Tengo un programa que descarga ficheros de un FTP y los procesa. Los
> ficheros son grandes (cientos de MB, tardan varios minutos en bajar),
> y el procesado es bastante pesado. Como no es crítico tener los datos
> procesados en tiempo real, he decidido meter el procesado en un hilo,
> para que se vaya haciendo de fondo mientras me sigo bajando datos por
> otro lado. Hay algo que no funciona, porque el servidor FTP me da
> timeouts, y el procesado no es concurrente, sino que secuencial.
>
> La clase hilo es muy sencilla:
> class MyThread ( threading.Thread):
>     def __init__ ( self, opciones):
>         self.opciones = opciones
>         threading.Thread.__init__ ( self )
>     def run ( self ):
>         #Procesar cosas blah blah blah
>
> La lógica del programa principal viene siendo un bucle en el servidor
> FTP remoto. Para cada fichero que se va a descargar, éste se descarga,
> se lanza el hilo del procesado una vez lo hemos descargado, y vuelta a
> empezar.
>
> El hilo para procesar cada fichero se lanza de la siguiente manera:
> MyThread( opciones).start()
>
> El proceso funciona, pero me da que no es concurrente. Hay algo obvio
> de lo que me estoy olvidando?

No sé si te he entendido bien, pero me da que has tenido un
encontronazo con el GIL (Global Interpreter Lock).

Por más hebras que tengas, sólamente una de ellas se ejecuta
concurrentemente en todo momento por culpa del GIL. El multihilo de
python (CPython) funciona bien cuando el programa tiene esperas en la
recepción de datos o cuando interactúa con el usuario, pero no
conseguirás gran cosa en procesos pesados como el de que tu caso.

Prueba a usar "forking", o bien pásate a otro python como jython o
ironpython cuyas hebras no tienen el problema del GIL.




Más información sobre la lista de distribución Python-es