Python Language
Computación paralela
Buscar..
Observaciones
Debido al GIL (bloqueo de intérprete global), solo una instancia del intérprete de python se ejecuta en un solo proceso. Por lo tanto, en general, el uso de subprocesos múltiples solo mejora los cálculos de E / S enlazados, no los de CPU. Se recomienda el módulo de multiprocessing
si desea paralelizar las tareas relacionadas con la CPU.
GIL se aplica a CPython, la implementación más popular de Python, así como a PyPy. Otras implementaciones como Jython y IronPython no tienen GIL .
Uso del módulo multiprocesamiento para paralelizar tareas.
import multiprocessing
def fib(n):
"""computing the Fibonacci in an inefficient way
was chosen to slow down the CPU."""
if n <= 2:
return 1
else:
return fib(n-1)+fib(n-2)
p = multiprocessing.Pool()
print(p.map(fib,[38,37,36,35,34,33]))
# Out: [39088169, 24157817, 14930352, 9227465, 5702887, 3524578]
A medida que la ejecución de cada llamada a fib
ocurre en paralelo, el tiempo de ejecución del ejemplo completo es 1.8 × más rápido que si se hiciera de forma secuencial en un procesador dual.
Python 2.2+
Usando scripts de Padres e Hijos para ejecutar código en paralelo
niño.py
import time
def main():
print "starting work"
time.sleep(1)
print "work work work work work"
time.sleep(1)
print "done working"
if __name__ == '__main__':
main()
parent.py
import os
def main():
for i in range(5):
os.system("python child.py &")
if __name__ == '__main__':
main()
Esto es útil para tareas de solicitud / respuesta HTTP independientes o para selección / inserción de base de datos. Los argumentos de la línea de comando también se pueden dar al script child.py . La sincronización entre scripts se puede lograr si todos los scripts revisan regularmente un servidor separado (como una instancia de Redis).
Usando una extensión C para paralelizar tareas
La idea aquí es mover los trabajos intensivos en computación a C (usando macros especiales), independientemente de Python, y hacer que el código C libere el GIL mientras está funcionando.
#include "Python.h"
...
PyObject *pyfunc(PyObject *self, PyObject *args) {
...
Py_BEGIN_ALLOW_THREADS
// Threaded C code
...
Py_END_ALLOW_THREADS
...
}
Usando el módulo PyPar para paralelizar
PyPar es una biblioteca que utiliza la interfaz de paso de mensajes (MPI) para proporcionar paralelismo en Python. Un ejemplo simple en PyPar (como se ve en https://github.com/daleroberts/pypar) se ve así:
import pypar as pp
ncpus = pp.size()
rank = pp.rank()
node = pp.get_processor_name()
print 'I am rank %d of %d on node %s' % (rank, ncpus, node)
if rank == 0:
msh = 'P0'
pp.send(msg, destination=1)
msg = pp.receive(source=rank-1)
print 'Processor 0 received message "%s" from rank %d' % (msg, rank-1)
else:
source = rank-1
destination = (rank+1) % ncpus
msg = pp.receive(source)
msg = msg + 'P' + str(rank)
pypar.send(msg, destination)
pp.finalize()