J'ai une méthode à l'intérieur d'une classe qui a besoin de faire beaucoup de travail en boucle, et je voudrais répartir le travail sur tous mes cœurs.
J'ai écrit le code suivant, qui fonctionne si j'utilise un map
normal, mais avec pool.map
renvoie une erreur.
import multiprocessing
pool = multiprocessing.Pool(multiprocessing.cpu_count() - 1)
class OtherClass:
def run(sentence, graph):
return False
class SomeClass:
def __init__(self):
self.sentences = [["Some string"]]
self.graphs = ["string"]
def some_method(self):
other = OtherClass()
def single(params):
sentences, graph = params
return [other.run(sentence, graph) for sentence in sentences]
return list(pool.map(single, Zip(self.sentences, self.graphs)))
SomeClass().some_method()
Erreur:
AttributeError: impossible de décaper l'objet local 'SomeClass.some_method..single'
Pourquoi ne peut-il pas décaper single
? J'ai même essayé de déplacer single
vers la portée du module global (pas à l'intérieur de la classe - le rend indépendant du contexte):
import multiprocessing
pool = multiprocessing.Pool(multiprocessing.cpu_count() - 1)
class OtherClass:
def run(sentence, graph):
return False
def single(params):
other = OtherClass()
sentences, graph = params
return [other.run(sentence, graph) for sentence in sentences]
class SomeClass:
def __init__(self):
self.sentences = [["Some string"]]
self.graphs = ["string"]
def some_method(self):
return list(pool.map(single, Zip(self.sentences, self.graphs)))
SomeClass().some_method()
et j'obtiens l'erreur suivante:
AttributeError: Impossible d'obtenir l'attribut 'single' sur le module 'main' de '.../test.py'
Vous démarrez le pool avant de définir votre fonction et vos classes, de cette façon les processus enfants ne peuvent hériter aucun code. Déplacez votre piscine au fond et protégez-la avec if __name__ == '__main__':
import multiprocessing
class OtherClass:
def run(self, sentence, graph):
return False
def single(params):
other = OtherClass()
sentences, graph = params
return [other.run(sentence, graph) for sentence in sentences]
class SomeClass:
def __init__(self):
self.sentences = [["Some string"]]
self.graphs = ["string"]
def some_method(self):
return list(pool.map(single, Zip(self.sentences, self.graphs)))
if __name__ == '__main__': # <- prevent RuntimeError for 'spawn'
# and 'forkserver' start_methods
with multiprocessing.Pool(multiprocessing.cpu_count() - 1) as pool:
print(SomeClass().some_method())