Solución:
creo que el Pool
La clase suele ser más conveniente, pero depende de si desea que los resultados estén ordenados o desordenados.
Supongamos que desea crear 4 cadenas aleatorias (por ejemplo, podría ser un generador de ID de usuario aleatorio más o menos):
import multiprocessing as mp
import random
import string
# Define an output queue
output = mp.Queue()
# define a example function
def rand_string(length, output):
""" Generates a random string of numbers, lower- and uppercase chars. """
rand_str="".join(random.choice(
string.ascii_lowercase
+ string.ascii_uppercase
+ string.digits)
for i in range(length))
output.put(rand_str)
# Setup a list of processes that we want to run
processes = [mp.Process(target=rand_string, args=(5, output)) for x in range(4)]
# Run processes
for p in processes:
p.start()
# Exit the completed processes
for p in processes:
p.join()
# Get process results from the output queue
results = [output.get() for p in processes]
print(results)
# Output
# ['yzQfA', 'PQpqM', 'SHZYV', 'PSNkD']
Aquí, el orden probablemente no importe. No estoy seguro de si hay una mejor manera de hacerlo, pero si quiero realizar un seguimiento de los resultados en el orden en que se llaman las funciones, normalmente devuelvo tuplas con una ID como primer elemento, por ejemplo,
# define a example function
def rand_string(length, pos, output):
""" Generates a random string of numbers, lower- and uppercase chars. """
rand_str="".join(random.choice(
string.ascii_lowercase
+ string.ascii_uppercase
+ string.digits)
for i in range(length))
output.put((pos, rand_str))
# Setup a list of processes that we want to run
processes = [mp.Process(target=rand_string, args=(5, x, output)) for x in range(4)]
print(processes)
# Output
# [(1, '5lUya'), (3, 'QQvLr'), (0, 'KAQo6'), (2, 'nj6Q0')]
Esto me permite ordenar los resultados entonces:
results.sort()
results = [r[1] for r in results]
print(results)
# Output:
# ['KAQo6', '5lUya', 'nj6Q0', 'QQvLr']
La clase de piscina
Ahora a su pregunta: ¿En qué se diferencia esto del Pool
¿clase? Normalmente preferirías Pool.map
para devolver una lista ordenada de resultados sin pasar por el aro de crear tuplas y ordenarlas por ID. Por lo tanto, diría que suele ser más eficiente.
def cube(x):
return x**3
pool = mp.Pool(processes=4)
results = pool.map(cube, range(1,7))
print(results)
# output:
# [1, 8, 27, 64, 125, 216]
De manera equivalente, también hay un método de “aplicar”:
pool = mp.Pool(processes=4)
results = [pool.apply(cube, args=(x,)) for x in range(1,7)]
print(results)
# output:
# [1, 8, 27, 64, 125, 216]
Ambos Pool.apply
y Pool.map
bloqueará el programa principal hasta que haya finalizado un proceso.
Ahora, también tienes Pool.apply_async
y Pool.map_async
, que devuelven el resultado tan pronto como el proceso ha finalizado, que es esencialmente similar al Process
clase anterior. La ventaja puede ser que le proporcionen el conveniente apply
y map
funcionalidad que conoces de la función incorporada de Python apply
y map
Puede hacer esto fácilmente con pypeln:
import pypeln as pl
stage = pl.process.map(
CreateMatrixMp,
range(self.numPixels),
workers=poolCount,
maxsize=2,
)
# iterate over it in the main process
for x in stage:
# code
# or convert it to a list
data = list(stage)