2015-08-26 4 views
0

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

# ------------------------- 
# main.py 
# ------------------------- 
import multiprocessing 
import foo 

def bar(a): 
    foo.test() 

if __name__ == "__main__": 
    pool = multiprocessing.Pool(5) 
    pool.map(bar, [1] * 15) 

# ---------------------------- 
# foo.py 
# ---------------------------- 
import api # Note the indirect import. 

def test(): 
    print(api.a) 

# ---------------------------- 
# api.py 
# ---------------------------- 
print("Imported") 
a = 5 

Для меня этот пример выдает что-то вроде:

Imported 
Imported 
5 
5 
5 
5 
5 
5 
5 
5 
5 
5 
5 
Imported 
5 
5 
5 
5 

Обратите внимание, что модуль api импортируется (т.е. выполняется) несколько раз. Как я мог избежать этого? Я хочу запустить код внутри модуля api ровно один раз (например, статическая инициализация в C), и я хочу, чтобы результирующие состояния (в данном случае api.a) были доступны из других процессов, но только инициализировались один раз.

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

+0

уточнения пожалуйста, какие части кода лежат в каком модуле. Я предполагаю, что код выше не находится в том же файле. – Pynchia

+0

@Pynchia Добавляем больше комментариев, с какого файла начинается – WorldSEnder

+0

OK спасибо (BTW, комментарии начинаются с #). Затем объясните, что вы намереваетесь сделать. Поведение, которое вы получаете, - именно то, чего вы должны ожидать от данного сценария. Проблема в том, чего вы пытаетесь достичь/зачем вам это нужно? – Pynchia

ответ

0

Каждый процесс имеет собственный экземпляр интерпретатора, поэтому ваш модуль api импортирован несколько раз. (Новый процесс начинается каждый раз, когда Imported был напечатан).

Более подробно об этом в official documentatioin

+1

Это объяснение проблемы, но на самом деле не решает Это. – WorldSEnder

+0

Запросить ввод пользователя в основном процессе, а затем предоставить данные в ваш пул. – trollknurr

Смежные вопросы