2010-11-11 21 views
12

je suis arrivé unAttributeError: l'objet '_MainProcess n'a pas de attribut '_exiting'

AttributeError: '_MainProcess' object has no attribute '_exiting' 

à partir d'une application Python. Malheureusement ce code doit exécuter Python 2.5 et donc le module processing aujourd'hui connu sous le nom multiprocessing. Ce que je faisais est de créer un Process avec un Queue et un put un élément dans la file d'attente du processus principal. En regardant dans le code processing.queue, je peux voir qu'un thread d'alimentation est démarré. Ce thread d'alimentation vérifie alors currentProcess()._exiting, mais currentProcess() évalue à un _MainProcess qui n'a pas cet attribut comme peut être vu dans le module processing.process. Comment résoudre ceci? Est-ce un bug dans processing? Si oui, puis-je simplement l'utiliser en utilisant currentProcess()._exiting = False?

exemple minimal:

#!/usr/bin/python 

import processing 
import processing.queue 

class Worker(processing.Process): 
    def __init__(self): 
     processing.Process.__init__(self) 
     self.queue = processing.queue.Queue() 

    def run(self): 
     element = self.queue.get() 
     print element 

if __name__ == '__main__': 
    w = Worker() 
    w.start() 
    # To trigger the problem, any non-pickleable object is to be passed here. 
    w.queue.put(lambda x: 1) 
    w.join() 
+0

Pouvez-vous poster un extrait qui reproduit l'erreur? Aussi, j'aime vraiment le mot * monkeypatch *. Dans l'attente de l'utiliser bientôt :) –

+0

Je crois qu'il y a une bonne façon de faire ce que vous voulez sans patcher. – khachik

+0

@ Space_C0wb0y Je suis désolé, j'ai eu un peu de problèmes avec la réduction de ces 3k lignes de code à un plus petit exemple. : -/ –

Répondre

1

Je ne sais pas pourquoi vous voulez décaper une fonction dans ce cas, si vous voulez vraiment faire jeter un oeil à cette réponse: Is there an easy way to pickle a python function (or otherwise serialize its code)?

autrement , cela fonctionne pour python 2.6 (je sais que vous cherchez 2.5 mais je n'ai pas 2.5). J'ai remplacé votre fonction lambda avec une fonction régulière et fournir cela au constructeur de traitement:

from multiprocessing import Process, Queue 

def simple(): 
    return 1 

class Worker(Process): 
    def __init__(self, args): 
     Process.__init__(self, args=args) 
     self.queue = Queue() 

    def run(self): 
     element = self.queue.get() 
     print element 

if __name__ == '__main__': 
    w = Worker(args=[simple]) 
    w.start() 
    w.join() 
+0

Je suis désolé, mais vous avez complètement manqué le point. Le problème est qu'il n'est pas évident à partir du message d'erreur que l'objet non-pickleable a été passé. Le lambda est juste un exemple pour un objet non-pickleable. –

+0

mais c'est pourquoi je vous ai donné le lien pour décorer une fonction python et vous pouvez mettre la fonction décapée dans votre file d'attente, et quand vous l'obtenez de votre file d'attente, vous pouvez reconstruire la fonction – DrDee

+0

Vous manquez toujours le point. Le problème initial était le message d'erreur. La moitié de la solution a découvert qu'il était causé par un objet non-pickleable. Travailler autour d'objets non-pickleable est trivial une fois que vous savez quelle est la cause. La partie manquante consiste à corriger le message d'erreur. –