переменная класса python не будет обновляться в многопроцессорной среде - PullRequest
0 голосов
/ 15 июня 2019

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

class state_mangment():
  def __init__(self):
    print('__init__')
    self.last_save = -1

  def update_state(self):
    self.last_save  =self.last_save + 1
    return self.last_save

from multiprocessing import Process, Lock
def f(l, i,persist_state ):
    l.acquire()
    try:

        print('last save is ',persist_state.update_state(),' should be ',i)
    finally:
        l.release()

if __name__ == '__main__':
    lock = Lock()
    persist_state = state_mangment()
    processes = []

    for num in range(10):
        p = Process(target=f, args=(lock, num,persist_state ))
        processes.append(p)
        p.start()

    for p in processes:
      p.join()

    print(persist_state.last_save)  

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

__init__
last save is  0  should be  0
last save is  0  should be  1
last save is  0  should be  2
last save is  0  should be  3
last save is  0  should be  4
last save is  0  should be  5
last save is  0  should be  6
last save is  0  should be  7
last save is  0  should be  8
last save is  0  should be  9
-1
    

1 Ответ

1 голос
/ 16 июня 2019

В вашем коде есть несколько ошибок. Функция, запускаемая multiprocessing.Process(), не разделяет адресное пространство родительского процесса. Вот почему манипулирование объектом persist_state не отражается в родительском процессе. Вы можете использовать объект multiprocessing.Lock() таким образом, потому что этот класс был разработан для работы таким образом, когда используется в контексте multiprocessing.Process(). Это не означает, что вы можете манипулировать состоянием произвольных объектов и отражать эти манипуляции в родительском процессе.

См. Это описание класса Manager () для одного способа решения этой проблемы.

...