¿Cuál es la diferencia entre ThreadPool vs Pool en el módulo de multiprocesamiento de Python?

¿Cuál es la diferencia entre ThreadPool y Pool en el módulo de multiprocessing ? Cuando pruebo mi código, esta es la principal diferencia que veo:

 from multiprocessing import Pool import os, time print("hi outside of main()") def hello(x): print("inside hello()") print("Proccess id: ", os.getpid()) time.sleep(3) return x*x if __name__ == "__main__": p = Pool(5) pool_output = p.map(hello, range(3)) print(pool_output) 

Veo el siguiente resultado:

 hi outside of main() hi outside of main() hi outside of main() hi outside of main() hi outside of main() hi outside of main() inside hello() Proccess id: 13268 inside hello() Proccess id: 11104 inside hello() Proccess id: 13064 [0, 1, 4] 

Con “ThreadPool”:

 from multiprocessing.pool import ThreadPool import os, time print("hi outside of main()") def hello(x): print("inside hello()") print("Proccess id: ", os.getpid()) time.sleep(3) return x*x if __name__ == "__main__": p = ThreadPool(5) pool_output = p.map(hello, range(3)) print(pool_output) 

Veo el siguiente resultado:

 hi outside of main() inside hello() inside hello() Proccess id: 15204 Proccess id: 15204 inside hello() Proccess id: 15204 [0, 1, 4] 

Mis preguntas son:

    • ¿Por qué se ejecuta el “fuera __main __ ()” cada vez en el Pool ?

    • multiprocessing.pool.ThreadPool no genera nuevos procesos? ¿Simplemente crea nuevos hilos?

    • Si es así, ¿cuál es la diferencia entre usar multiprocessing.pool.ThreadPool en lugar de solo un módulo de threading ?

    No veo ninguna documentación oficial de ThreadPool ninguna parte, ¿puede alguien ayudarme donde pueda encontrarla?

    multiprocessing.pool.ThreadPool comporta igual que multiprocessing.Pool con la única diferencia que utiliza subprocesos en lugar de procesos para ejecutar la lógica de los trabajadores.

    La razón por la que ves

     hi outside of main() 

    La impresión se realiza varias veces con el multiprocessing.Pool La agrupación se debe al hecho de que la agrupación generará 5 procesos independientes. Cada proceso inicializará su propio intérprete de Python y cargará el módulo que resultará en la ejecución de la print nivel superior nuevamente.

    Tenga en cuenta que esto ocurre solo si se utiliza el método de creación del proceso de generación (solo el método disponible en Windows). Si usa el fork (Unix), verá el mensaje impreso solo una vez como para los hilos.

    El multiprocessing.pool.ThreadPool no está documentado ya que su implementación nunca se ha completado. Carece de pruebas y documentación. Puedes ver su implementación en el código fuente .

    Creo que la siguiente pregunta natural es: ¿cuándo usar un grupo basado en subprocesos y cuándo usar uno basado en procesos?

    La regla de oro es:

    • Trabajos enlazados de IO -> multiprocessing.pool.ThreadPool
    • Trabajos vinculados a la CPU -> multiprocessing.Pool
    • Trabajos híbridos -> depende de la carga de trabajo, por lo general prefiero el multiprocessing.Pool

    En Python 3 es posible que desee echar un vistazo a las implementaciones del grupo concurrent.future.Executor .