Saltar al contenido

Multiprocesamiento de Python: ¿Cómo saber utilizar Pool o Process?

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)
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *