Использование модуля многопроцессорности
Я пытаюсь использовать модуль многопроцессорности в python 2.6, но, видимо, я чего-то не понимаю. Я бы ожидал, что ниже приведенный класс добавит числа, отправленные ему с помощью add(), и вернет сумму в методе get_result(). В приведенном ниже коде печатается "0", я бы хотел, чтобы он печатал "2". Что я пропустил?
import multiprocessing
class AdderProcess(multiprocessing.Process):
def __init__(self):
multiprocessing.Process.__init__(self)
self.sum = 0
self.queue = multiprocessing.JoinableQueue(5)
self.daemon = True
self.start()
def run(self):
while True:
number = self.queue.get()
self.sum += number
self.queue.task_done()
def add(self, number):
self.queue.put(number)
def get_result(self):
self.queue.join()
return self.sum
p = AdderProcess()
p.add(1)
p.add(1)
print p.get_result()
PS. Эта проблема решена. Спасибо за ответы! Просто чтобы облегчить для читателей, здесь полная рабочая версия:
import multiprocessing
class AdderProcess(multiprocessing.Process):
def __init__(self):
multiprocessing.Process.__init__(self)
self.sum = multiprocessing.Value('d', 0.0)
self.queue = multiprocessing.JoinableQueue(5)
self.daemon = True
self.start()
def run(self):
while True:
number = self.queue.get()
self.sum.value += number
self.queue.task_done()
def add(self, number):
self.queue.put(number)
def get_result(self):
self.queue.join()
return self.sum.value
p = AdderProcess()
p.add(1)
p.add(1)
print p.get_result()
Ответы
Ответ 1
Измените self.sum = 0
на self.sum = multiprocessing.Value('d', 0.0)
и используйте self.sum.value
для доступа или изменения значения.
class AdderProcess(multiprocessing.Process):
def __init__(self):
...
self.sum = multiprocessing.Value('d', 0.0)
...
def run(self):
while True:
number = self.queue.get()
self.sum.value += number # <-- use self.sum.value
self.queue.task_done()
def get_result(self):
self.queue.join()
return self.sum.value # <-- use self.sum.value
Проблема заключается в следующем: после вызова self.start()
в __init__
основной процесс отменяет дочерний процесс. Все значения копируются. Теперь есть две версии p
. В основном процессе p.sum
равно 0. В дочернем процессе вызывается метод run
и p.sum
добавляется к 2. Но когда основной процесс вызывает p.get_result()
, его версия p
все еще имеет p.sum
равно 0.
Таким образом, 0 печатается.
Если вы хотите разделить значение float между процессами, вам необходимо использовать механизм совместного доступа, например mp.Value
.
См. "" Состояние совместного доступа между процессами" для получения дополнительных опций о том, как делиться значениями.
Ответ 2
self.sum
составляет 2... в этом процессе:
def run(self):
while True:
number = self.queue.get()
print "got %s from queue" % number
print "Before adding - self.sum = %d" % self.sum
self.sum += number
print "After adding - self.sum = %d" % self.sum
self.queue.task_done()
[ 13:56 [email protected] ~ ]$ ./mp.py
got 1 from queue
Before adding - self.sum = 0
After adding - self.sum = 1
got 1 from queue
Before adding - self.sum = 1
After adding - self.sum = 2
См. многопроцессорность 16.3.1.4. - Совместное использование процессов между процессами о том, как сделать self.sum
одинаковым в разных процессах.