Невозможно вернуть добавленное значение из процесса Python - PullRequest
1 голос
/ 02 декабря 2010

Я использую Python 2.6.5 в Ubuntu 8.10.

Для проекта, над которым я работаю, мне нужно запустить несколько процессов одновременно и сохранить каждый их вывод в свои соответствующие списки. Поскольку я не могу вернуть выходное значение непосредственно из процесса, я передаю выходной список в качестве аргумента моей целевой функции и добавляю выходные данные в этот список. Проблема в том, что когда я пытаюсь получить доступ к этому списку после запуска процесса, список все еще пуст. Ниже приведена упрощенная версия проблемы, а также сообщение об ошибке.

Код:

from multiprocessing import Process
import sys, math, os,commands

outputs = []

def calculate(a,b,outputs):
    c = a*b
    outputs.append(c)
    #return c

outputs1 = []

p1 = Process(target = calculate, args = (2,3,outputs1))

p1.start()
p1.join()

print 'len(outputs1) = ' + str(len(outputs1))

print 'outputs1 = ' + str(outputs1[0])

Ошибка:

len(outputs1) = 0
Traceback (most recent call last):
  File "append_test.py", line 23, in <module>
    print 'outputs1 = ' + str(outputs1[0])
IndexError: list index out of range

Я пытаюсь сохранить каждый процесс полностью независимым от других, опасаясь повреждения данных. Я пытался использовать модуль Array из многопроцессорной обработки, но кажется, что append специфичен для списков. Когда я запускаю точно такой же код с потоком вместо процесса, я получаю желаемый результат без проблем, из-за чего я полагаю, что это проблема совместного использования памяти.

Ответы [ 2 ]

3 голосов
/ 02 декабря 2010

Когда вы используете отдельные процессы, каждый процесс получает свою собственную копию всего в памяти.Вот почему родительский процесс никогда не видит ничего в своем outputs: каждый дочерний процесс добавляет к своей собственной копии outputs.

. Вам необходимо использовать некоторую форму межпроцессного взаимодействия.Библиотека Python multiprocessing предоставляет для этого две функции: каналы и очереди .

Например, используя Queue:

>>> from multiprocessing import Process, Queue
>>> def f(q): q.put("hello from the child process")
... 
>>> q = Queue()
>>> p = Process(target=f, args=(q,))
>>> p.start()
>>> p.join()
>>> q.get()
'hello from the child process'
0 голосов
/ 03 декабря 2010

Раздел под названием Обмен объектами между процессами в онлайн-документации модуля multiprocessing говорит, что он [только] «поддерживает два типа канала связи между процессами» и продолжает упоминать Очереди и Трубы . Примечательно, что не упоминает list объекты типа outputs1. Это имеет смысл, потому что два процесса не разделяют память AFAIK.

Я не уверен, но я также подозреваю, что вам может понадобиться поместить раздел вашего кода, который создает процесс и запускает его, и т. Д. Внутри предложения if __name__ == '__main__':, чтобы подпроцесс не мог создать подпроцесс.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...