[Python-es] computación paralela y concurrente
tny
a.porrua en gmail.com
Dom Ene 2 01:47:41 CET 2011
El sáb, 01-01-2011 a las 22:56 +0100, David Villa escribió:
> Hola:
>
> Si no me equivoco, tu callback.Callback es prácticamente equivalente
> al
> functools.partial() de la librería estándar.
>
Tienes toda la razón, acabo de mirarlo y es exactamente lo mismo.
Así que para la proxima revisión posiblemente marque callback.Callback
como obsoleto y recomiende el uso de functools.partial() en su lugar.
Muchas Gracias.
> Y así a primera vista, diría que gran parte de tu módulo fork puede
> hacerse
> con multiprocessing (de Python-2.6) y concurrent.futures (de
> Python-3.2). De
> éste último estaría muy bien tener un backport. En todo caso tendría
> que
> mirarlo más despacio.
>
> Saludos
concurrent.futures no lo conocía, lo acabo de mirar por encima, y parece
muy interesante a la hora de ejecutar funciones de forma paralela, pero
no veo que establezca ningún modo de comunicación entre procesos.
Mi librería pretende ser más sencilla y de mayor nivel que
Multiprocessing.
Personalmente me resulta más intuitivo emplear eventos y callbacks.
De todos modos no son excluyentes, puedes usar mi sistema de eventos, y
también semaforos, queues y demás sistemas de sincronización y
comunicación que multiprocessing ofrece.
un ejemplo que usa pykiss.fork y multiprocessing.Array
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from pykiss import fork
from multiprocessing import Array
arr = Array('i', 3) #este objeto será compartido por todos los procesos
#este proceso hará operaciones con los valores de arr
class Operar_Process(fork.Process):
def __init__(self, unixsocket):
fork.Process.__init__(self, unixsocket)
#asignamos los callbacks a los eventos
self.instance_events['sumar'] = self.sumar
self.instance_events['multiplicar'] = self.multiplicar
#suma lo que haya en arr y lo devuelve con un evento
def sumar(self, event):
res = sum(arr)
self.send_event(keyword='resultado', resultado=res)
#multiplica lo que haya en arr y lo devuelve con un evento
def multiplicar(self, event):
res = 1
for i in arr:
res*=i
self.send_event(keyword='resultado', resultado=res)
#este proceso asignará valores a arr
class Asignar_Process(fork.Process):
def __init__(self, unixsocket):
fork.Process.__init__(self, unixsocket)
self.instance_events['asignar'] = self.asignar
def asignar(self, event):
indice = event['indice']
valor = event['valor']
arr[indice]=valor
#Este driver hace más cómodo enviar el evento 'asignar'
class Asignar_Driver(fork.Driver):
def __setitem__(self, key, value):
self.send_event(keyword = 'asignar', indice = key,
valor = value)
#este callback en el proceso principal mostrará los resultados
def resultado(driver, evento):
print evento['resultado']
#creamos el objeto principal que gestiona los procesos
control = fork.Control()
#asignamos el callback al evento
control.events['resultado'] = resultado
#creamos los procesos
operar = control.fork(fork.Driver, Operar_Process)
asignar = control.fork(Asignar_Driver, Asignar_Process)
#les mandamos hacer cosas
asignar[0] = 5
asignar[1] = 7
operar.send_event(keyword = 'sumar')
asignar[2] = 12
operar.send_event(keyword = 'sumar')
asignar[0] = 15
operar.send_event(keyword = 'multiplicar')
#Procesamos todos los eventos que hayan llegado al proceso principal
control.do()
Un saludo
Más información sobre la lista de distribución Python-es