Pensé que simplificaría los ejemplos más simples copiados desde arriba, trabajando para mí en Py3.6. Más simple es multiprocessing.Pool
:
import multiprocessing
import time
def worker(x):
time.sleep(1)
return x
pool = multiprocessing.Pool()
print(pool.map(worker, range(10)))
Puede establecer el número de procesos en la piscina con, por ejemplo, Pool(processes=5)
. Sin embargo, el valor predeterminado es el recuento de CPU, así que déjelo en blanco para las tareas vinculadas a la CPU. (Las tareas vinculadas a E / S a menudo se adaptan a los subprocesos de todos modos, ya que los subprocesos en su mayoría están esperando, por lo que pueden compartir un núcleo de CPU). Pool
También se aplica la optimización de fragmentación .
(Tenga en cuenta que el método de trabajo no se puede anidar dentro de un método. Inicialmente definí mi método de trabajo dentro del método al que hace la llamada pool.map
, para mantenerlo todo autocontenido, pero luego los procesos no pudieron importarlo, y arrojé "AttributeError : No se puede encurtir el objeto local external_method..inner_method ". Más aquí . Puede estar dentro de una clase.)
(Aprecio la impresión original de la pregunta especificada en 'represent!'
lugar de hacerlo time.sleep()
, pero sin ella pensé que algunos códigos se ejecutaban simultáneamente cuando no era así).
Py3 ProcessPoolExecutor
también tiene dos líneas ( .map
devuelve un generador, por lo que necesita list()
):
from concurrent.futures import ProcessPoolExecutor
with ProcessPoolExecutor() as executor:
print(list(executor.map(worker, range(10))))
Con simples Process
es:
import multiprocessing
import time
def worker(x, queue):
time.sleep(1)
queue.put(x)
queue = multiprocessing.SimpleQueue()
tasks = range(10)
for task in tasks:
multiprocessing.Process(target=worker, args=(task, queue,)).start()
for _ in tasks:
print(queue.get())
Úselo SimpleQueue
si todo lo que necesita es put
y get
. El primer bucle inicia todos los procesos, antes de que el segundo realice las queue.get
llamadas de bloqueo . No creo que haya ninguna razón para llamar p.join()
también.
multiprocessing.Queue
, en lugar de unManager
aquí. El uso deManager
requiere generar un proceso completamente nuevo, que es excesivo cuandoQueue
lo haría.