Сохранять единый счет во время многопроцессорной обработки?

У меня есть программа python, которая запускает симуляцию Монте-Карло, чтобы найти ответы на вопросы о вероятности. Я использую многопроцессорность, и здесь он находится в псевдокоде

import multiprocessing def runmycode(result_queue): print "Requested..." while 1==1: iterations +=1 if "result found (for example)": result_queue.put("result!") print "Done" processs = [] result_queue = multiprocessing.Queue() for n in range(4): # start 4 processes process = multiprocessing.Process(target=runmycode, args=[result_queue]) process.start() processs.append(process) print "Waiting for result..." result = result_queue.get() # wait for process in processs: # then kill them all off process.terminate() print "Got result:", result 

Я хотел бы расширить это, чтобы я мог поддерживать единый счетчик числа итераций, которые были запущены. Как если бы поток 1 выполнялся 100 раз, а поток 2 выполнялся 100 раз, то я хочу показать 200 итераций всего, как печать на консоль. Я имею в виду переменную iterations в поточном процессе. Как я могу убедиться, что ВСЕ потоки добавляются к одной и той же переменной? Я думал, что использование Global версии iterations будет работать, но это не так.

One Solution collect form web for “Сохранять единый счет во время многопроцессорной обработки?”

Обычные глобальные переменные не разделяются между процессами так, как они распределяются между потоками. Вам необходимо использовать структуру данных, ориентированную на процесс. Для вашего прецедента multiprocessing.Value должно отлично работать:

 import multiprocessing def runmycode(result_queue, iterations): print("Requested...") while 1==1: # This is an infinite loop, so I assume you want something else here with iterations.get_lock(): # Need a lock because incrementing isn't atomic iterations.value += 1 if "result found (for example)": result_queue.put("result!") print("Done") if __name__ == "__main__": processs = [] result_queue = multiprocessing.Queue() iterations = multiprocessing.Value('i', 0) for n in range(4): # start 4 processes process = multiprocessing.Process(target=runmycode, args=(result_queue, iterations)) process.start() processs.append(process) print("Waiting for result...") result = result_queue.get() # wait for process in processs: # then kill them all off process.terminate() print("Got result: {}".format(result)) print("Total iterations {}".format(iterations.value)) 

Несколько примечаний:

  1. Я явно передал Value для детей, чтобы поддерживать код совместимым с Windows, который не может делиться глобальными переменными чтения / записи между родителями и дочерними.
  2. Я защищал приращение блокировкой, потому что это не атомная операция, и она подвержена условиям гонки.
  3. Я добавил if __name__ == "__main__": guard, снова, чтобы помочь с совместимостью Windows, и просто как лучшая общая практика.
Python - лучший язык программирования в мире.