Понимание переменных статического класса между процессами в Python - PullRequest
0 голосов
/ 18 сентября 2018

Я создавал разных рабочих демонов того же класса, что и их цель, используя модуль multiprocessing.Этот класс динамически импортирует различные модули в зависимости от контекста и сохраняет эти модули в статическом словаре области действия.Я начал думать, из-за статического словаря уровня класса, будет ли весь импорт, сделанный всеми предыдущими работниками (который может быть уже прекращен), быть доступным / присутствующим у всех будущих работников?на самом деле не происходило, и импорт прошлых работников не был настоящим рабочим, как хотелось бы.Но задумался почему так.Поэтому я создал небольшой пример, имитирующий то же самое.Ниже приведены два примера.Оба включают один и тот же Cmodule.py, который содержит целевой класс работника C.Разница только в temp.py, это тоже только в аргументе mup.Process().Первый пример терпит неудачу, в том смысле, что член статического dict в классе C, добавленный прошлым работником, присутствует в будущем работнике.Хотя это не относится ко второму примеру.

Cmodule.py

class C:
    staticDict = {}

    def __init__(self, condition):
        if condition:
            C.staticDict['a'] = 'a'
        else:
            C.staticDict['b'] = 'b'
        self.printStaticDict()

    def printStaticDict(self):
        print(C.staticDict)

Пример 1 - temp.py

import multiprocessing as mup
from Cmodule import *

def newProc3():
    c = C(True)

def newProc4():
    c = C(False)

newProc3Obj = mup.Process(newProc3())
newProc4Obj = mup.Process(newProc4())
newProc3Obj.start()
newProc4Obj.start()

Пример 2 - temp.py

import multiprocessing as mup
from Cmodule import *

def newProc3():
    c = C(True)

def newProc4():
    c = C(False)

newProc3Obj = mup.Process(target=newProc3)  //this differs from example 1
newProc4Obj = mup.Process(target=newProc4)  //this differs from example 1
newProc3Obj.start()
newProc4Obj.start()

Пример 1 - output

{'a': 'a'}
{'a': 'a', 'b': 'b'}

Пример 2- output

{'a': 'a'}
{'b': 'b'}

Обратите внимание, что в выходном примере 1 значение ключа 'a':'a' сохраняется у второго работника, но это не так в примере 2. Итак, в чем разница междудва?

newProc4Obj = mup.Process(newProc4())

и

newProc4Obj = mup.Process(target=newProc4)

И это нормально, что я пытаюсь сделать, как описано в первом абзаце вопроса?

1 Ответ

0 голосов
/ 18 сентября 2018

Есть две большие - и вполне очевидные - различия между вашими двумя версиями.

В первом примере вы вызываете newProc3 и newProc4 и передаете результаты этих вызовов - в данном случае None - в качестве аргумента group Process .

Во втором примере вы передаете newProc3 / newProc4 функции в качестве аргумента target.

Это означает, что в первом случае обе ваши функции newProcX выполняются в родительском процессе, поэтому вы кажетесь для получения ожидаемого результата - но на самом деле вы этого не делаете: Process У них нет цели, поэтому они вообще ничего не выполняют.

Второй пример - это правильный способ настройки Процесса - путем передачи ему вызываемого объекта в качестве цели - но поскольку это разные процессы, родительский процесс C.staticDict не подвержен влиянию.

Если вы хотите обмениваться данными между процессами, вы должны использовать Queue как , объясненное в прекрасном руководстве .

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