J'ai fait des recherches en premier et je n'ai pas trouvé de réponse à ma question. J'essaie d'exécuter plusieurs fonctions en parallèle en Python.
J'ai quelque chose comme ça:
files.py
import common #common is a util class that handles all the IO stuff
dir1 = 'C:\folder1'
dir2 = 'C:\folder2'
filename = 'test.txt'
addFiles = [25, 5, 15, 35, 45, 25, 5, 15, 35, 45]
def func1():
c = common.Common()
for i in range(len(addFiles)):
c.createFiles(addFiles[i], filename, dir1)
c.getFiles(dir1)
time.sleep(10)
c.removeFiles(addFiles[i], dir1)
c.getFiles(dir1)
def func2():
c = common.Common()
for i in range(len(addFiles)):
c.createFiles(addFiles[i], filename, dir2)
c.getFiles(dir2)
time.sleep(10)
c.removeFiles(addFiles[i], dir2)
c.getFiles(dir2)
Je veux appeler func1 et func2 et les faire fonctionner en même temps. Les fonctions n'interagissent pas entre elles ou sur le même objet. Pour le moment, je dois attendre la fin de func1 avant de démarrer func2. Comment faire quelque chose comme ci-dessous:
process.py
from files import func1, func2
runBothFunc(func1(), func2())
Je veux être en mesure de créer les deux répertoires assez près en même temps parce que chaque minute, je compte le nombre de fichiers créés. Si le répertoire n'est pas là, cela gâchera mon timing.
Réponses:
Vous pouvez utiliser
threading
oumultiprocessing
.En raison des particularités de CPython , il
threading
est peu probable d'atteindre un véritable parallélisme. Pour cette raison,multiprocessing
est généralement un meilleur pari.Voici un exemple complet:
Les mécanismes de démarrage / d'assemblage de processus enfants peuvent facilement être encapsulés dans une fonction le long de votre
runBothFunc
:la source
Cela peut être fait élégamment avec Ray , un système qui vous permet de paralléliser et de distribuer facilement votre code Python.
Pour paralléliser votre exemple, vous devez définir vos fonctions avec le
@ray.remote
décorateur, puis les appeler avec.remote
.Si vous passez le même argument aux deux fonctions et que l'argument est volumineux, un moyen plus efficace de le faire consiste à utiliser
ray.put()
. Cela évite que le gros argument soit sérialisé deux fois et d'en créer deux copies mémoire:Si
func1()
etfunc2()
retournez des résultats, vous devez réécrire le code comme suit:L'utilisation de Ray présente un certain nombre d'avantages par rapport au module multiprocesseur . En particulier, le même code s'exécutera sur une seule machine ainsi que sur un cluster de machines. Pour plus d'avantages de Ray, consultez cet article connexe .
la source
Si vos fonctions font principalement du travail d' E / S (et moins de travail sur le processeur) et que vous avez Python 3.2+, vous pouvez utiliser un ThreadPoolExecutor :
Si vos fonctions font principalement du travail sur le processeur (et moins de travail d'E / S) et que vous avez Python 2.6+, vous pouvez utiliser le module multiprocesseur :
la source
Si vous êtes un utilisateur de Windows et que vous utilisez python 3, cet article vous aidera à faire de la programmation parallèle en python.Lorsque vous exécutez la programmation en pool d'une bibliothèque multiprocesseur habituelle, vous obtiendrez une erreur concernant la fonction principale de votre programme. C'est parce que Windows n'a pas de fonctionnalité fork (). Le post ci-dessous donne une solution au problème mentionné.
http://python.6.x6.nabble.com/Multiprocessing-Pool-woes-td5047050.html
Depuis que j'utilisais le python 3, j'ai changé le programme un peu comme ceci:
Après cette fonction, le code de problème ci-dessus est également modifié un peu comme ceci:
Et j'ai eu la sortie comme:
Je pense que cet article peut être utile pour certains utilisateurs de Windows.
la source
Il n'y a aucun moyen de garantir que deux fonctions s'exécuteront en synchronisation l'une avec l'autre, ce qui semble être ce que vous voulez faire.
Le mieux que vous puissiez faire est de diviser la fonction en plusieurs étapes, puis d'attendre que les deux se terminent aux points de synchronisation critiques en utilisant
Process.join
des mentions de réponse comme @ aix.C'est mieux que
time.sleep(10)
parce que vous ne pouvez pas garantir les horaires exacts. En attendant explicitement, vous dites que les fonctions doivent être exécutées en exécutant cette étape avant de passer à la suivante, au lieu de supposer que cela sera fait dans les 10 ms, ce qui n'est pas garanti en fonction de ce qui se passe sur la machine.la source
Il semble que vous ayez une seule fonction que vous devez appeler sur deux paramètres différents. Cela peut être fait avec élégance en utilisant une combinaison de
concurrent.futures
etmap
avec Python 3.2+Maintenant, si votre opération est liée aux E / S, vous pouvez utiliser le
ThreadPoolExecutor
comme tel:Notez comment
map
est utilisé ici pourmap
votre fonction à la liste des arguments.Maintenant, si votre fonction est liée au processeur, vous pouvez utiliser
ProcessPoolExecutor
Si vous n'êtes pas sûr, vous pouvez simplement essayer les deux et voir lequel vous donne les meilleurs résultats.
Enfin, si vous souhaitez imprimer vos résultats, vous pouvez simplement le faire:
la source