Python Multitraitement Processus ou de la Piscine pour ce que je suis en train de faire?
Je suis nouveau sur le multitraitement en Python et à essayer de comprendre si je dois utiliser la Piscine ou le Processus par lequel deux fonctions asynchrones. Les deux fonctions que j'ai faites curl appels et analyser l'information en 2 listes distinctes. En fonction de la connexion internet, chaque fonction peut prendre environ 4 secondes. Je me rends compte que le goulot d'étranglement est la connexion internet et le multitraitement de ne pas accélérer beaucoup, mais il serait sympa de les avoir à la fois le coup d'envoi asynchrone. De Plus, c'est une excellente expérience d'apprentissage pour moi de le faire en python multi-traitement parce que je vais l'utiliser plus tard.
J'ai lu Python multiprocessing.Piscine: utilisation s'appliquent, apply_async ou de la carte? et il était utile, mais encore a mes propres questions.
D'une manière que je pourrais le faire est:
def foo():
pass
def bar():
pass
p1 = Process(target=foo, args=())
p2 = Process(target=bar, args=())
p1.start()
p2.start()
p1.join()
p2.join()
Questions que j'ai pour cette mise en œuvre est:
1) Depuis rejoindre les blocs jusqu'à ce que le processus appelant est terminé...est-ce à dire p1 processus avant la fin de la p2 processus est démarré? J'ai toujours compris l' .join() sera la même que la piscine.appliquer() et de la piscine.apply_sync().get() où le processus parent ne peut pas lancer un autre processus(tâche) jusqu'à l'actuel, la course est terminée.
L'autre alternative serait quelque chose comme:
def foo():
pass
def bar():
pass
pool = Pool(processes=2)
p1 = pool.apply_async(foo)
p1 = pool.apply_async(bar)
Questions que j'ai pour cette mise en œuvre serait:
1) ai-je besoin d'une piscine.close(), piscine.join()?
2) Serait de la piscine.map (), ce sont tous complets avant que je puisse obtenir des résultats? Et si oui, sont-ils encore couru asynch?
3) Comment la piscine.apply_async() diffèrent de faire de chaque processus avec piscine.appliquer()
4) Comment serait-ce différent de la précédente mise en œuvre de Processus?
Vous devez vous connecter pour publier un commentaire.
Les deux scénarios de la liste d'accomplir la même chose mais de façon légèrement différente.
Le premier scénario commence deux processus distincts (appelons P1 et P2) et commence l'exécution de P1
foo
et P2 de coursebar
, et attend jusqu'à ce que les deux processus ont terminé leurs tâches respectives.Le deuxième scénario commence deux processus (appeler T1 et T2) et commence à
foo
sur T1 ou T2, et commence alorsbar
sur T1 ou T2. Ensuite, le code attend jusqu'à ce que les deux appels de fonction sont de retour.De sorte que le résultat net est en fait le même, mais dans le premier cas, vous êtes garanti
foo
etbar
sur des processus différents.Que pour les questions spécifiques que vous aviez sur la simultanéité, la
.join()
méthode sur unProcess
ne fait bloc jusqu'à ce que le processus est terminé, mais parce que vous avez appelé.start()
sur les deux P1 et P2 (dans votre premier scénario), avant de rejoindre, les deux processus s'exécute de façon asynchrone. L'interprète, cependant, attendre jusqu'à ce que P1 finitions avant de tenter d'attendre de la P2 à la fin.Pour vos questions à propos de la piscine scénario, vous devez utiliser techniquement
pool.close()
mais ça dépend de ce que vous pourriez en avoir besoin pour la suite (si il va juste hors de portée, alors vous n'avez pas besoin de fermer nécessairement).pool.map()
est un genre complètement différent de l'animal, parce qu'elle distribue un tas d'arguments pour la même fonction (de manière asynchrone), sur l'ensemble du pool de processus, et attend jusqu'à ce que tous les appels de fonction ont terminée avant de retourner la liste des résultats.Puisque vous êtes de l'extraction de données à partir de curl appels que vous êtes IO-lié. Dans de tels cas grequests pourrait venir dans maniable. Ce sont vraiment ni le processus ni le fils, mais coroutines - léger threads. Cela vous permettra d'envoyer de manière asynchrone des requêtes HTTP, et ensuite utiliser
multiprocessing.Pool
pour accélérer le CPU de la partie.Oui,
p2.join()
est appelée aprèsp1.join()
a retourné sensp1
a fini.Vous pourriez vous retrouver avec des processus orphelins sans faire
close()
etjoin()
(si le processus de servir indéfiniment)Ils sont couru de façon asynchrone, mais le
map()
est bloqué jusqu'à ce que toutes les tâches sont effectuées.pool.apply()
bloque, donc, fondamentalement, vous ne le traitement de façon synchrone.Les Chances sont un travailleur est fait avec
foo
avant d'appliquerbar
donc, vous pourriez vous retrouver avec un seul ouvrier qui fait tout le travail. Aussi, si l'un de vos travailleurs meurtPool
génère automatiquement un nouveau (vous auriez besoin de réappliquer la tâche).Pour résumer: je préfère aller avec
Pool
- il est parfait pour les producteurs et les consommateurs des cas et prend soin de toutes les tâches-la distribution de la logique.p2
sera rejoint aprèsp1
a été fini de les rejoindre. Désolé pour le malentendu. Bien sûr, les deux procédés, le coup d'envoi dans les meilleurs délaisstart()
est de retour.