Использование многопроцессорного модуля

Я пытаюсь использовать многопроцессорный модуль в 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()

2 ответа

Решение

+ Изменить 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 печатается.

Если вы хотите разделить значение с плавающей запятой между процессами, вам необходимо использовать механизм совместного использования, такой как mp.Value,

См. " Совместное использование состояния между процессами" для получения дополнительной информации о том, как делиться значениями.

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 jon@host ~ ]$ ./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 быть одинаковым в разных процессах.

Другие вопросы по тегам