Python, Pathos – Namespace auf neuen Thread ändern

Ich begann mit pathos.multiprocessing, um einige der Kopfschmerzen beim Beizen von nicht-trivialen Objekten wie logging.logger zu entfernen. Allerdings laufe ich in das Problem, dass die Importe nicht in einem neuen Thread verfügbar sind. Infolgedessen muss ich diese Module in diesem neuen Thread "neu importieren". Insbesondere wird dieser Fall aufgrund des folgenden Fehlers nicht ausgeführt:

NameError: global name 'os' is not defined e Found at: multiprocess.pool result = True, func(*args, **kwds) 

Der folgende Code funktioniert nicht, obwohl er unter dem eingebauten Multiprocessing-Modul funktionieren würde:

 import os import multiprocessing from pathos.multiprocessing import ProcessPool class SomethingDoer: '''Probably does some thing''' def doAllSomethings(self, allSomethings): cores = multiprocessing.cpu_count()-1 pool = ProcessPool(nodes=cores) for something in allSomethings: someProcess = self.doSomething, something pool.apipe(*someProcess) def doSomething(self,something): pathString = os.path.join(r"\foo%i"%something,"bar.log") print pathString 

Der folgende Code wird jedoch mit pathos.multiprocessing funktionieren

 import multiprocessing from pathos.multiprocessing import ProcessPool class SomethingDoer: '''Probably does some thing''' def doAllSomethings(self,allSomethings): cores = multiprocessing.cpu_count()-1 pool = ProcessPool(nodes=cores) for something in allSomethings: someProcess = self.doSomething, something pool.apipe(*someProcess) def doSomething(self,something): import os pathString = os.path.join(r"\foo%i"%something,"bar.log") print pathString 

Mit folgendem Beispiel

 import time p = SomethingDoer() p.doAllSomethings(range(3)) while 1: time.sleep(.1) 

Beide Stücke von Code sollten die folgende Ausgabe (offensichtlich nicht unbedingt in der gleichen Reihenfolge) ausgeben:

 \foo0\bar.log \foo1\bar.log \foo2\bar.log 

Ich möchte in der Lage sein, eine Variante des ersten Code-Snippets zu verwenden, da dies mit dem Rest der Codebasis übereinstimmt. Allerdings wird jede Hilfe sehr geschätzt.

One Solution collect form web for “Python, Pathos – Namespace auf neuen Thread ändern”

Ich bin der pathos Autor. Wenn Sie Ihr pathos aktualisieren, um multiprocess zu verwenden (anstelle der processing , die eine viel ältere Gabel ist), sollte Ihr Code wie beabsichtigt funktionieren.

 >>> import os >>> import pathos.helpers as multiprocessing >>> from pathos.multiprocessing import ProcessPool >>> >>> class SomethingDoer: ... '''Probably does some thing''' ... def doAllSomethings(self, allSomethings): ... cores = multiprocessing.cpu_count()-1 ... pool = ProcessPool(nodes=cores) ... for something in allSomethings: ... someProcess = self.doSomething, something ... pool.apipe(*someProcess) ... def doSomething(self,something): ... pathString = os.path.join(r"\foo","bar.log") ... >>> p = SomethingDoer() >>> p.doAllSomethings(range(3)) >>> p.doSomething(range(3)) >>> 

Beachten Sie, Sie möchten vielleicht die aktuellste Version von dill , die bessere Unterstützung für Pickle-Tracing von globalen Variablen zu bekommen. Um zu modifizieren, wie dill (und damit pathos ) globale Variablen verarbeitet, kannst du dies tun:

 >>> import dill >>> dill.settings['recurse'] = True 

Keine Garantie, welche Einstellungen das Beste für Ihren Fall sind, aber es gibt Ihnen Optionen.

EDIT: Als Antwort auf dein Update. Dies funktioniert: Hier werden Sie feststellen, dass ich einen "get" mache, anstatt den Pool am Leben zu heben und darauf zu warten, dass die Antworten abgerufen werden.

 import os import pathos.helpers as multiprocessing from pathos.multiprocessing import ProcessPool class SomethingDoer: '''Probably does some thing''' def doAllSomethings(self,allSomethings): cores = multiprocessing.cpu_count()-1 pool = ProcessPool(cores) for something in allSomethings: someProcess = self.doSomething, something pool.apipe(*someProcess).get() #pool.clear() def doSomething(self,something): pathString = os.path.join(r"\foo%i"%something,"bar.log") print pathString if __name__ == '__main__': import time p = SomethingDoer() print p.doAllSomethings(range(3)) 

Eine Alternative ist, nicht zu verwenden, aber dann uncomment die clear … im Wesentlichen Zerstörung der Pool. pathos hält an Pools in einem Singleton, so dass mehrere Läufe haben weniger Overhead bei der Einrichtung eines Pools jedes Mal.

Die Ausgabe, die ich bekomme, ist nicht genau das, was du vorhergesagt hast.

 >$ python testme.py \foo0/bar.log \foo1/bar.log \foo2/bar.log None 

Wenn Sie feststellen, dass dies unerwartetes Verhalten ist – und auch falsch, füllen Sie bitte einen Fehlerbericht aus. Oh, und die Einstellungen, die ich vorgeschlagen habe, machen keinen Unterschied – und auch nicht mit einer "neuartigen" Klasse SomethingDoer(object)

Python ist die beste Programmiersprache der Welt.