2014-04-17 1 views
1

J'essaye de faire un programme multiprocess avec Python. Je Importez le module multiprocessus et j'essaie de commencer à traiter comme ceci:Processus ne pas engendrer python

p = Process(target=self.Parse) 
    p.start() 
    p.join() 

Dans la classe I ont un compteur de filetage intérieur et j'incrémenter le compteur à chaque fois que le est un processus donné naissance. Mais lorsque j'imprime le nombre de threads, le nombre ne s'incrémente pas. Alors j'appelle multiprocessing.active_children() mais cela retourne une liste vide. Le programme ne génère-t-il pas vraiment les threads ou les processus ou le signale-t-il simplement? le code est le suivant:

def run(self): 
    if self.cont: 
    while self.nxtLink or (self.thread>1): 
     print(active_children()) 
     if self.thread<=self.count: 
      p = Process(target=self.Parse) 
      p.start() 
      p.join() 
     else: 
      self.crawl(nxtLink.popleft()) 

La fonction Parse:

def Parse(self): 
    self.thread+=1 
    self.lock.acquire() 
    next = self.nxtLink.popleft() 
    self.lock.release() 
    results = parser(next[0],next[1]) 
    #print("In Parse") 
    self.broken[next[0]] = results.broken 
    for i in results.foundLinks: 
     if(self.thread<=self.count+5): 
      p = Process(target = self.request, args = (i,next[0])) 
      p.start() 
      p.join() 
     else: 
      while (self.thread>self.count+5): 
       pass #Waits for the thread count to drop before spawning a new thread. 
      p = Process(target = self.request, args = (i,next[0])) 
      p.start() 
      p.join() 
    self.lock.acquire() 
    self.thread-=1 
    self.lock.release() 

Enfin, la fonction de la demande:

def request(self, requestURL, requestingPageURL): 
    # print(requestURL) 
    self.lock.acquire() 
    self.thread+=1 
    self.lock.release() 
    try: 
     before = list(self.prev) 
     self.lock.acquire() 
     self.prev.append(requestURL) 
     self.lock.release() 
     if(requestURL in before): 
      #print(before) 
      return 
     nextRequest = req.urlopen(requestURL) 
     self.lock.acquire() 
     self.nxtLink.append((requestURL,nextRequest)) 
     self.lock.release() 
    except err.URLError: 
     self.lock.acquire() 
     try: 
      self.broken[requestingPageURL].append(requestURL) 
     except KeyError: 
      self.broken[requestingPageURL] = [requestURL] 
     self.lock.release() 
    finally: 
     self.lock.acquire() 
     self.thread-=1 
     self.lock.release() 

Je suis vraiment coincé pourquoi ses processus ne se reproduisent Mais le programme Tout fonctionne bien alors je suis un peu confus. Join() attend la fin du processus.

Répondre

0

Lorsque vous avez une séquence comme:

p = Process(target=self.Parse) 
p.start() 
p.join() 

Le programme attend des parents pour l'enfant à remplir si vous n'avez pas des enfants actifs au moment où vous faites le chèque. Vous feriez mieux d'appeler simplement les fonctions au lieu d'engendrer des enfants parce que vous attendez qu'ils se terminent de toute façon. Il est commun pour un code comme celui-ci de placer les objets Process dans une liste, de faire un autre travail, et de revenir les rejoindre plus tard quand le travail est terminé.

Vous pouvez ajouter un code de débogage qui permet de suivre ce qui a été appelé pour vérifier que votre code d'enfant est en cours d'exécution:

import time 
with open('/tmp/trace.txt', 'a') as fp: 
    fp.write(time.asctime() + '\n') 

une bonne idée en général pour ajouter un peu l'exploitation forestière aux processus vous frayer afin que vous puissiez suivre des choses comme les exceptions python dans votre code.

+0

hmmm Je ne me suis pas rendu compte que join() l'a fait. Une question de plus, comment mettriez-vous le processus dans une liste, puis rejoignez-les? – rady

+0

@ user2985233, il existe plusieurs façons de le faire en fonction de ce que fait votre code. Consultez les docs pour multiprocessing.Pool et aussi des exemples d'utilisation multiprocessing.Queue pour les conseils. Vous pouvez passer une file d'attente au processus et lui faire envoyer un message «terminé» lorsque vous avez terminé. Ensuite, la lecture de la file d'attente vous indique quel processus doit être rejoint ensuite. – tdelaney

+0

Donc, je devrais avoir tous les threads dans une liste et continuellement interroger la liste pour voir ce que le processus est fait? et ensuite le rejoindre? – rady

Questions connexes