クラス内にループ内で多くの作業を行う必要があるメソッドがあり、すべてのコアに作業を分散させたいと考えています。
次のコードを作成しました。通常のmap
を使用すると動作しますが、pool.map
はエラーを返します。
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()
エラー:
AttributeError:ローカルオブジェクト 'SomeClass.some_method..single'をピクルできません
なぜsingle
を漬けられないのですか? (クラス内ではなく、コンテキストに依存しないように)グローバルモジュールスコープにmovesingle
しようとしました:
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()
そして、次のエラーが表示されます。
AttributeError: '.../test.py'からモジュール 'main'の属性 'single'を取得できません
関数とクラスを定義する前にプールを開始しているため、子プロセスはコードを継承できません。プールの開始位置を一番下に移動し、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())