マルチプロセッシングモジュールに問題があります。私はたくさんのファイルからデータをロードするためにそのmapメソッドでワーカーのプールを使用しており、それぞれに対してカスタム関数でデータを分析しています。ファイルが処理されるたびに、処理されるファイルの数を追跡できるように、カウンターを更新したいと思います。サンプルコードは次のとおりです。
def analyze_data( args ):
# do something
counter += 1
print counter
if __== '__main__':
list_of_files = os.listdir(some_directory)
global counter
counter = 0
p = Pool()
p.map(analyze_data, list_of_files)
これに対する解決策が見つかりません。
問題は、プロセス間でcounter
変数が共有されないことです。各プロセスは独自のローカルインスタンスを作成し、それをインクリメントします。
プロセス間で状態を共有するために使用できるいくつかの手法については、ドキュメントの このセクション を参照してください。あなたの場合、ワーカー間で Value
インスタンスを共有したいかもしれません
これがあなたの例の実際のバージョンです(いくつかのダミーの入力データがあります)。実際には回避しようとするグローバル値を使用していることに注意してください。
from multiprocessing import Pool, Value
from time import sleep
counter = None
def init(args):
''' store the counter for later use '''
global counter
counter = args
def analyze_data(args):
''' increment the global counter, do something with the input '''
global counter
# += operation is not atomic, so we need to get a lock:
with counter.get_lock():
counter.value += 1
print counter.value
return args * 10
if __== '__main__':
#inputs = os.listdir(some_directory)
#
# initialize a cross-process counter and the input lists
#
counter = Value('i', 0)
inputs = [1, 2, 3, 4]
#
# create the pool of workers, ensuring each one receives the counter
# as it starts.
#
p = Pool(initializer = init, initargs = (counter, ))
i = p.map_async(analyze_data, inputs, chunksize = 1)
i.wait()
print i.get()
競合状態のバグのないカウンタークラス:
class Counter(object):
def __init__(self):
self.val = multiprocessing.Value('i', 0)
def increment(self, n=1):
with self.val.get_lock():
self.val.value += n
@property
def value(self):
return self.val.value
Valueの組み込みロックを2回使用せずに高速なCounterクラス
class Counter(object):
def __init__(self, initval=0):
self.val = multiprocessing.RawValue('i', initval)
self.lock = multiprocessing.Lock()
def increment(self):
with self.lock:
self.val.value += 1
@property
def value(self):
return self.val.value
https://eli.thegreenplace.net/2012/01/04/shared-counter-with-pythons-multiprocessinghttps://docs.python.org/2/library/ multiprocessing.html#multiprocessing.sharedctypes.Valuehttps://docs.python.org/2/library/multiprocessing.html#multiprocessing.sharedctypes.RawValue