33 votes

Plusieurs threads en Python

Je suis nouveau sur Python et sur les threads. J'ai écrit du code python qui agit comme un robot d'indexation Web et recherche un mot clé spécifique sur les sites. Ma question est la suivante: comment utiliser des threads pour exécuter trois instances différentes de ma classe en même temps. Lorsque l'une des instances trouve le mot clé, toutes les trois doivent être fermées et cesser d'analyser le Web. Voici du code.

 class Crawler:
      def __init__(self):
            # the actual code for finding the keyword 

 def main():  
        Crawl = Crawler()

 if __name__ == "__main__":
        main()
 

Comment utiliser des threads pour que Crawler effectue trois analyses différentes en même temps?

54voto

Jeremy Banks Points 32470

Il ne semble pas être une (simple) de manière à mettre fin à un fil en Python.

Voici un exemple simple de l'exécution de plusieurs requêtes HTTP en parallèle:

import threading

def crawl():
    import urllib2
    data = urllib2.urlopen("http://www.google.com/").read()

    print "Read google.com"

threads = []

for n in range(10):
    thread = threading.Thread(target=crawl)
    thread.start()

    threads.append(thread)

# to wait until all three functions are finished

print "Waiting..."

for thread in threads:
    thread.join()

print "Complete."

Avec une charge supplémentaire, vous pouvez utiliser un multi-processus de l'approche qui est plus puissant et permet de mettre fin comme un fil de processus.

Je l'ai étendu l'exemple de l'utiliser. J'espère que ce sera utile pour vous:

import multiprocessing

def crawl(result_queue):
    import urllib2
    data = urllib2.urlopen("http://news.ycombinator.com/").read()

    print "Requested..."

    if "result found (for example)":
        result_queue.put("result!")

    print "Read site."

processs = []
result_queue = multiprocessing.Queue()

for n in range(4): # start 4 processes crawling for the result
    process = multiprocessing.Process(target=crawl, args=[result_queue])
    process.start()
    processs.append(process)

print "Waiting for result..."

result = result_queue.get() # waits until any of the proccess have `.put()` a result

for process in processs: # then kill them all off
    process.terminate()

print "Got result:", result

6voto

Winston Ewert Points 17746

Le démarrage d'un thread est facile:

thread = threading.Thread(function_to_call_inside_thread)
thread.start()

Créer un objet d'événement pour vous avertir lorsque vous avez terminé:

event = threading.Event()
event.wait() # call this in the main thread to wait for the event
event.set() # call this in a thread when you are ready to stop

Une fois que l'événement a mis le feu, vous aurez besoin d'ajouter du stop() les méthodes de vos robots.

for crawler in crawlers:
    crawler.stop()

Et puis d'appeler rejoindre sur les threads

thread.join() # waits for the thread to finish

Si vous avez n'importe quelle quantité de ce genre de programmation, vous aurez envie de regarder à la eventlet module. Il vous permet d'écrire "filée" code sans de nombreux inconvénients de filetage.

5voto

uʍop ǝpısdn Points 16540

Tout d'abord, si vous êtes nouveau à python, je ne recommanderais pas face à fils pourtant. S'habituer à la langue, puis attaquez-le multi-threading.

Cela dit, si votre objectif est de paralléliser (vous avez dit "exécuter en même temps"), vous devriez savoir qu'en python (ou au moins dans l'implémentation par défaut, Disponible) plusieurs threads ne SERA PAS vraiment s'exécuter en parallèle, même si plusieurs cœurs de processeurs sont disponibles. Lire sur le GIL (Global Interprète de Verrouillage) pour plus d'informations.

Enfin, si vous voulez toujours continuer, vérifiez la documentation Python pour le module threading. Je dirais Python docs sont aussi bons que les références d'obtenir, avec beaucoup d'exemples et d'explications.

0voto

Robotica Points 96

Pour résoudre ce problème, vous pouvez utiliser le module threading (qui, comme d'autres l'ont dit, ne le fera pas vrai parce que le filetage de la GIL) ou le module multiprocessing (selon la version de Python que vous utilisez). Ils sont très similaires Api, mais je vous recommande de multitraitement, car il est plus Pythonic, et je trouve que la communication entre les processus avec des Tuyaux assez facile.

Vous aurez envie d'avoir votre boucle principale, qui vous permettra de créer vos processus, et chacun de ces processus doivent fonctionner votre robot ont un tuyau de retour vers le thread principal. Votre processus devrait écouter un message sur le tuyau, faire un peu d'analyse, et d'envoyer un message sur le conduit s'il trouve quelque chose (avant de mettre fin). Vos principales boucle boucle sur chacun des tuyaux en arrière, à l'écoute de ce "trouvé quelque chose de" message. Une fois qu'il entend le message, il doit le renvoyer sur les tuyaux pour les autres processus, puis attendre pour eux de complet.

Plus d'informations peuvent être trouvées ici: http://docs.python.org/library/multiprocessing.html

0voto

Wael BEN ZID Points 149

Tout d'abord, le threading n'est pas une solution en Python. En raison de GIL, Threads ne fonctionne pas en parallèle. Vous pouvez donc gérer cela avec le multitraitement et vous serez limité par le nombre de cœurs de processeur.

Quel est l'objectif de votre travail? Vous voulez avoir un robot? Ou vous avez des objectifs académiques (apprentissage du threading et de Python, etc.)?

Un autre point, Crawl gaspille plus de ressources que d’autres programmes, alors quelle est votre vente?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X