[Python-es] computación paralela y concurrente
tny
a.porrua en gmail.com
Sab Ene 1 05:56:57 CET 2011
> Hola. Antes de nada, feliz año! :D
>
> He estado mirando la documentación de las bibliotecas que publicaste,
> y me genera una duda y ya que el lema es KISS, no seria mas simple
> usar un simple un "decorator class" para hacer esto lo que hace tu
> bibl. "fork"
>
> Aquí un ejemplos:
> http://paste.niwi.be/17/raw/
> http://paste.niwi.be/18/raw/
>
> Esta hecho con threads y ya se que no son escalables a múltiples
> núcleos, pero puedes substituirlo por "Process" y por casa llamada al
> método se generaría un proceso. Y no se si tu biblioteca tiene
> opciones de sincronizacion y la posibilidad de envío de mensajes entre
> procesos...(Lo digo que lo que viene de serie en python creo que es
> muchísimo mas completo y mas simple a mi parecer)
Mi biblioteca tiene dos partes, una que es para lanzar funciones y
ejecutar callbacks con sus valores de retorno, y otra que lanza procesos
que se comunican mediante eventos.
este ejemplo me parece muy kiss, creo que no necesita ni comentarios,
que se entiende sólo.
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import hashlib
from pykiss import fork
usuarios = ['admin', 'good', 'pepe']
passwords = ['admin', '123456', 'password']
passw = '6f1a2f61d94139dbddc3238d4f46ce2f'
control = fork.Control()
def comprobar(usuario, password):
if passw == hashlib.md5(usuario+'@'+password).hexdigest():
return (usuario, password)
def mostrar(retorno):
if retorno:
print "User:%s\nPassword:%s"%retorno
for usuario in usuarios:
for password in passwords:
control.fork_function(mostrar, comprobar, usuario, password)
control.main()
Lo mismo con procesos que se envían eventos.
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import hashlib
from pykiss import fork
from pykiss import callback
import sys
usuarios = ['user', 'admin', 'good', 'pepe']
passwords = ['', 'admin', '123456','good', 'password']
passw = '6f1a2f61d94139dbddc3238d4f46ce2f'
control = fork.Control()
class Comprobar_Process(fork.Process):
def __init__(self, unixsocket, user):
fork.Process.__init__(self, unixsocket)
self.instance_events['parar'] = self.parar
self.user = user
def parar(self, event):
raise fork.Break_loop_exception()
def main(self):
for password in passwords:
if passw == hashlib.md5(self.user+'@'+password).hexdigest():
self.send_event(keyword = 'user en pass encontrado', user=self.user,
password=password)
sys.exit()
else:
try:
self.poll.do(0)
except fork.Break_loop_exception:
break
self.send_event(keyword='process normaly ended',exit=0)
sys.exit(0)
def encontrado(driver, event):
print "User:%s\nPassword:%s"%(event['user'],event['password'])
for driver in control.drivers.itervalues():
driver.send_event(keyword = 'parar')
control.events['user en pass encontrado'] = encontrado
for usuario in usuarios:
control.fork(fork.Driver, callback.Callback(Comprobar_Process,
user=usuario))
control.main()
¿Cómo harías eso con decorator class y la biblioteca estandar?
¿Quedaría legible?
Cuando necesité trabajar con procesos leí y releí la biblioteca estandar
de python y te aseguro que me pareció demasiado complicado.
Ser demasiado completo está reñido con ser simple.
Así que hice sólo lo que necesitaba.
>
> En el apartado de creación de excepciones, en mi opinión, no ayudas en nada...
> Creo que es mas simple:
> class MyError(Exception): pass
>
> que:
> from pykiss.auto_exceptions import make_exception
> excepcion1 = make_exception('excepcion1')
>
> Ademas de las excepciones pueden tener sus propios métodos y variables
> de instancia, que serian también mucho mas simples de definir como
> siempre se define que con el método de tu biblioteca.
>
> Y antes de nada, como siempre, no quiero mal interpretaciones, solo
> genero una critica constructiva y no quiero ofender a nadie.
>
con esto:
class MyError(Exception): pass
no puedes luego hacer así:
raise MyError(msg='ha pasado tal cosa', foo='tralari', bar='tralará)
para luego en el except hacer así
except MyError as e:
print e.foo
y con MyError = make_exception('MyError') si puedes hacer todo eso.
Pero tienes tu parte de razón, porque simplemente bastaba con
class MyError(auto_exceptions.Base_exception): pass
A veces uno se obceca y va por el camino más dificil.
No sé cual quedará más legible...
Me lo pienso e igual cambio eso.
Todas son librerías que estaba usando yo en mis propios desarrollos,
porque lo encuentro más sencillo que hacerlo de otro modo, y me parecio
que podía ser de utilidad a más personas.
Así que las miré con lupa para eliminar cualquier bug que se me hubiera
escapado, y las comenté y documenté lo mejor que pude.
> Un saludo.
> Andrei.
>
>
No ofendes, y agradezco tu crítica, aquí estamos todos para aprender.
Más información sobre la lista de distribución Python-es