Le MultiThreading avec une boucle python
J'ai un tentez d'exécuter ce code Python sur plusieurs threads de mon processeur, mais je ne trouve pas comment allouer plusieurs threads. Je suis à l'aide de python 2.7 dans Jupyter (anciennement IPython).
Le premier code est ci-dessous (toute cette partie fonctionne parfaitement). C'est un web analyseur qui prend x
c'est à dire, une url entre my_list c'est à dire, une liste d'url et puis écrire un fichier CSV (où out_string est une ligne).
Code sans le MultiThreading
my_list = ['http://stackoverflow.com/', 'http://google.com']
def main():
with open('Extract.csv'), 'w') as out_file:
count_loop = 0
for x in my_list:
#================ Get title ==================#
out_string = ""
campaign = parseCampaign(x)
out_string += ';' + str(campaign.getTitle())
#================ Get Profile ==================#
if campaign.getTitle() != 'NA':
creator = parseCreator(campaign.getCreatorUrl())
out_string += ';' + str(creator.getCreatorProfileLinkUrl())
else:
pass
#================ Write ==================#
out_string += '\n'
out_file.write(out_string)
count_loop +=1
print '---- %s on %s ------- ' %(count_loop, len(my_list))
Code Multithread, mais ne fonctionne pas
from threading import Thread
my_list = ['http://stackoverflow.com/', 'http://google.com']
def main(x):
with open('Extract.csv'), 'w') as out_file:
count_loop = 0
for x in my_list:
#================ Get title ==================#
out_string = ""
campaign = parseCampaign(x)
out_string += ';' + str(campaign.getTitle())
#================ Get Profile ==================#
if campaign.getTitle() != 'NA':
creator = parseCreator(campaign.getCreatorUrl())
out_string += ';' + str(creator.getCreatorProfileLinkUrl())
else:
pass
#================ Write ==================#
out_string += '\n'
out_file.write(out_string)
count_loop +=1
print '---- %s on %s ------- ' %(count_loop, len(my_list))
for x in my_list:
t = Thread(target=main, args=(x,))
t.start()
t2 = Thread(target=main, args=(x,))
t2.start()
Je ne peux pas trouver un bon moyen de mettre en œuvre plus d'un thread à exécuter ce morceau de code, et je suis un peu confus, car la documentation n'est pas très facile à comprendre. Avec un noyau, ce code prend 2 heures de temps, le multi-threading me permettra de gagner beaucoup de temps!
Voici une version courte de mon code, la version réelle fait de 7 à 10 secondes par boucle car il y a beaucoup de demandes externe (API), de sorte 10s * 12 000 url pourraient être considérablement améliorées si chaque cœur de mon processeur sont utilisés, c'est à dire, core1 = 10s * 3000url s+ core2 = 10s * 3000urls + core3 = 10s * 3000urls + cœur4 = 10s * 3000urls en même temps...
Quand vous dites que le multithreading la version ne fonctionne pas, que voulez-vous dire. Est-il une erreur, ou est-il tout simplement pas courir plus vite? Vérifier à cette question, je ne pense pas que ipython utilise plusieurs cœurs, même avec filetage module. stackoverflow.com/a/204150/5889975
python n'est pas à l'écoute pour le multi thread pour beaucoup de raisons. essayez avec
multiprocessing
ou asyncio
.S'il vous plaît dites-nous ce que "ne pas travailler".
OriginalL'auteur SciPy | 2016-02-23
Vous devez vous connecter pour publier un commentaire.
Ok, permet de briser votre problème.
Tout d'abord votre méthode main() traite toutes les entrées et les sorties vers un fichier. Lorsque vous utilisez principale avec 2 fils le même travail est effectué par les deux threads. Vous avez besoin d'une méthode qui ne traite qu'une entrée et renvoie une sortie pour une entrée.
Maintenant, vous pouvez appeler cette méthode dans plusieurs threads et obtenir la sortie de chaque
x
séparément.Mais le problème est que cela va démarrer le n nombre de threads où n est le nombre d'éléments dans my_list. Ainsi, l'utilisation de
multiprocessing.Piscine
sera mieux ici. Donc, au lieu de cela, utiliserresult_list
auront des résultats de l'ensemble de la liste. Alors maintenant, vous pouvez l'enregistrer dans un fichier.vous avez raison
Pool.map
blocs jusqu'à ce qu'il traite l'ensemble de la liste des entrées. Mais ici, je ne pense pas que l'OP sera faire quelque chose entre les deuxapplyasync
et l'enregistrement de données dans un fichier, pour lequel nous avons besoin de soins sur le blocage de lamap
méthode. Plus de plus de[Pool.applyasync(f, x) for x in my_list]; Pool.close(); Pool.join();
est essentiellement égale à la Piscine.la carte en termes de blocage, logiquement.OriginalL'auteur Muhammad Tahir
Bien... la réponse à:
est:
(voir les commentaires de l'original post)
alors quelque chose est très mal ici.
Chers OP, les deux fils va faire exactement la même chose! Cela signifie que le premier thread va faire exactement la même chose que le deuxième.
Ce que vous pouvez faire est quelque chose comme ce qui suit:
Fondamentalement, vous pouvez penser à chaque processus/thread comme ayant sa propre "esprit". Cela signifie que dans votre code, le premier thread qui va faire le processus défini dans
main()
pour l'argumentx
(prises à partir de votre itération sur votre liste) et la seconde pour faire la même tâche (l'un dans lemain()
) pourx
.Ce que vous avez besoin est de formuler votre processus comme une procédure ayant un ensemble de paramètres d'entrée et de sortie. Ensuite, vous pouvez créer plusieurs processus, à chacune de leur donner l'un des paramètres d'entrée désirés, puis le processus de l'exécution de votre routine principale avec le bon paramètre.
Espère que cela aide. Voir aussi le code et je pense que vous le comprendrez.
Aussi, voir:
multitraitement carte et asynchrone de la carte (je ne me souviens pas maintenant le nom exact)
et
functools partielle
OriginalL'auteur Xxxo