¿Existe una clase Pool para subprocesos de trabajo , similar a la clase Pool del módulo de multiprocesamiento ?
Me gusta, por ejemplo, la forma fácil de paralelizar una función de mapa
def long_running_func(p):
c_func_no_gil(p)
p = multiprocessing.Pool(4)
xs = p.map(long_running_func, range(100))
Sin embargo, me gustaría hacerlo sin la sobrecarga de crear nuevos procesos.
Sé sobre el GIL. Sin embargo, en mi caso de uso, la función será una función C ligada a IO para la cual el contenedor de Python liberará el GIL antes de la llamada a la función real.
¿Tengo que escribir mi propio grupo de subprocesos?
from multiprocessing.pool import ThreadPool
.I know about the GIL. However, in my usecase, the function will be an IO-bound C function for which the python wrapper will release the GIL before the actual function call.
?Respuestas:
Me acabo de enterar de que en realidad hay una interfaz Pool basada en hilos en el
multiprocessing
módulo, sin embargo, está algo oculta y no está debidamente documentada.Se puede importar a través de
Se implementa utilizando una clase de proceso ficticia que envuelve un hilo de Python. Se puede encontrar esta clase de proceso basada en subprocesos,
multiprocessing.dummy
que se menciona brevemente en los documentos . Este módulo ficticio supuestamente proporciona toda la interfaz de multiprocesamiento basada en subprocesos.fuente
multiprocessing.dummy.Pool
/multiprocessing.pool.ThreadPool
son lo mismo, y ambos son grupos de subprocesos. Imitan la interfaz de un grupo de procesos, pero se implementan completamente en términos de subprocesos. Vuelve a leer los documentos, lo tienes al revés.multiprocessing.dummy
replica la API demultiprocessing
pero no es más que un contenedor alrededor delthreading
módulo".multiprocessing
en general se trata de procesos, pero para permitir el cambio entre procesos y subprocesos, ellos (principalmente) replicaron lamultiprocessing
APImultiprocessing.dummy
, pero respaldados con subprocesos, no procesos. El objetivo es permitirleimport multiprocessing.dummy as multiprocessing
cambiar el código basado en procesos a hilos.En Python 3 puedes usar
concurrent.futures.ThreadPoolExecutor
, es decir:Consulte los documentos para obtener más información y ejemplos.
fuente
sudo pip install futures
ThreadPoolExecutor
ymultiprocessing.dummy.Pool
?Sí, y parece tener (más o menos) la misma API.
fuente
ThreadPool
es diferente dePool
. La importación correcta esfrom multiprocessing.pool import ThreadPool
.Para algo muy simple y ligero (ligeramente modificado desde aquí ):
Para admitir devoluciones de llamada al finalizar la tarea, solo puede agregar la devolución de llamada a la tupla de la tarea.
fuente
Queue.get()
está bloqueando) hasta que finaliza el programa, después de lo cual finalizan automáticamente.Queue.join()
en realidad se unirá a la cola de tareas, no a subprocesos de trabajo. Entonces, cuando la cola está vacía,wait_completion
el sistema operativo cosecha los subprocesos y el subproceso.pool.wait_completion()
regresa. El resultado es que los hilos siguen construyéndose.Hola, para usar el grupo de subprocesos en Python, puede usar esta biblioteca:
y para su uso, esta biblioteca hace así:
Los subprocesos son la cantidad de subprocesos que desea y las tareas son una lista de tareas que la mayoría asigna al servicio.
fuente
.close()
y.join()
las llamadas y que las causas.map()
para terminar antes hayan terminado todos los hilos. Sólo una advertencia.Aquí está el resultado que finalmente terminé usando. Es una versión modificada de las clases de dgorissen anterior.
Expediente:
threadpool.py
Para usar la piscina
fuente
#!/usr/bin/python3
)for i, d in enumerate(delays):
y luego ignoras eli
valor?i
durante una carrera.create_task
hay ¿Para qué sirve?La sobrecarga de crear los nuevos procesos es mínima, especialmente cuando solo son 4 de ellos. Dudo que este sea un punto clave de rendimiento de su aplicación. Manténgalo simple, optimice dónde tiene que hacerlo y hacia dónde apuntan los resultados del perfil.
fuente
No hay una agrupación integrada basada en subprocesos. Sin embargo, puede ser muy rápido implementar una cola de productor / consumidor con la
Queue
clase.De: https://docs.python.org/2/library/queue.html
fuente
concurrent.futures
módulo.from multiprocessing.pool import ThreadPool
Otra forma puede ser agregar el proceso al grupo de colas de hilos
fuente