Общая переменная в многопроцессорной обработке Python
Первый вопрос: в чем разница между Value и Manager().Value?
Во-вторых, возможно ли использовать целочисленную переменную без использования Value? Ниже приведен мой пример кода. То, что я хочу, это получить диктат со значением целое число, а не значение. То, что я сделал, это просто изменил все это после процесса. Есть ли более простой способ?
from multiprocessing import Process, Manager
def f(n):
n.value += 1
if __name__ == '__main__':
d = {}
p = []
for i in range(5):
d[i] = Manager().Value('i',0)
p.append(Process(target=f, args=(d[i],)))
p[i].start()
for q in p:
q.join()
for i in d:
d[i] = d[i].value
print d
1 ответ
Когда вы используете Value
Вы получаете ctypes
объект в разделяемой памяти, который по умолчанию синхронизируется с помощью RLock
, Когда вы используете Manager
Вы получаете SynManager
объект, управляющий процессом сервера, который позволяет манипулировать значениями объекта другими процессами. Вы можете создать несколько прокси, используя один и тот же менеджер; нет необходимости создавать нового менеджера в вашем цикле:
manager = Manager()
for i in range(5):
new_value = manager.Value('i', 0)
Manager
могут быть разделены между компьютерами, в то время как Value
ограничен одним компьютером. Value
будет быстрее (запустите приведенный ниже код, чтобы увидеть), поэтому я думаю, что вы должны использовать это, если вам не нужно поддерживать произвольные объекты или обращаться к ним по сети.
import time
from multiprocessing import Process, Manager, Value
def foo(data, name=''):
print type(data), data.value, name
data.value += 1
if __name__ == "__main__":
manager = Manager()
x = manager.Value('i', 0)
y = Value('i', 0)
for i in range(5):
Process(target=foo, args=(x, 'x')).start()
Process(target=foo, args=(y, 'y')).start()
print 'Before waiting: '
print 'x = {0}'.format(x.value)
print 'y = {0}'.format(y.value)
time.sleep(5.0)
print 'After waiting: '
print 'x = {0}'.format(x.value)
print 'y = {0}'.format(y.value)
Подвести итоги:
- использование
Manager
создавать несколько общих объектов, включая диктовки и списки. использованиеManager
обмениваться данными между компьютерами в сети. - использование
Value
или жеArray
когда нет необходимости обмениваться информацией по сети и типы вctypes
достаточно для ваших нужд. Value
быстрее чемManager
,
Предупреждение
Кстати, по возможности следует избегать совместного использования данных между процессами / потоками. Приведенный выше код, вероятно, будет работать как положено, но увеличит время, необходимое для выполнения foo
и все станет странным. Сравните вышесказанное с:
def foo(data, name=''):
print type(data), data.value, name
for j in range(1000):
data.value += 1
Вам понадобится Lock
чтобы сделать эту работу правильно.
Я не особенно осведомлен обо всем этом, поэтому, возможно, кто-то еще придет и предложит больше понимания. Я подумал, что внесу ответ, так как этот вопрос не привлекает внимания. Надеюсь, это немного поможет.