Recherche…


Remarques

En raison du GIL (Global Interpreter Lock), une seule instance de l'interpréteur python s'exécute en un seul processus. Donc, en général, l'utilisation du multi-threading n'améliore que les calculs liés aux entrées-sorties, pas ceux liés au processeur. Le module de multiprocessing est recommandé si vous souhaitez paralléliser les tâches liées au processeur.

GIL s'applique à CPython, l'implémentation la plus populaire de Python, ainsi que PyPy. D'autres implémentations telles que Jython et IronPython n'ont pas de GIL .

Utilisation du module de multitraitement pour paralléliser des tâches

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]

Comme l'exécution de chaque appel à fib se déroule en parallèle, le temps d'exécution de l'exemple complet est 1,8 fois plus rapide que s'il était exécuté de manière séquentielle sur un processeur double.

Python 2.2+

Utiliser les scripts Parent et Children pour exécuter du code en parallèle

child.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()

Ceci est utile pour les tâches de requête / réponse HTTP parallèles et indépendantes ou pour les sélections / insertions de base de données. Des arguments de ligne de commande peuvent également être donnés au script child.py . La synchronisation entre les scripts peut être réalisée par tous les scripts vérifiant régulièrement un serveur distinct (comme une instance Redis).

Utiliser une extension C pour paralléliser des tâches

L'idée ici est de déplacer les travaux intensifs en calcul vers C (en utilisant des macros spéciales), indépendamment de Python, et de faire en sorte que le code C libère le GIL pendant qu'il fonctionne.

#include "Python.h"
...
PyObject *pyfunc(PyObject *self, PyObject *args) {
    ...
    Py_BEGIN_ALLOW_THREADS
    // Threaded C code
    ...
    Py_END_ALLOW_THREADS
    ...
}

Utiliser le module PyPar pour paralléliser

PyPar est une bibliothèque qui utilise l'interface de transmission de messages (MPI) pour fournir le parallélisme en Python. Un exemple simple dans PyPar (vu à https://github.com/daleroberts/pypar) ressemble à ceci:

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()


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow