Доступ к переменной, назначенной в многопроцессорной функции - PullRequest
0 голосов
/ 06 июля 2018

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

from flask import Flask, render_template
from flask_socketio import SocketIO, send
import bot
import sys
sys.path = sys.path + ['filepath']
from BigLearnPy import BigLearn
from multiprocessing import Process

app = Flask(__name__)
app.config['SECRET_KEY'] = 'password'
socketio = SocketIO(app)

def loadModel():
    BigLearn.LoadEmbeddingEngine()
    emb = BigLearn.EmbeddingEngine('filepath')

@app.route('/')
def index():
    return render_template('index.html')

@socketio.on('message')
def handleMessage(msg):
    send(msg, broadcast=True)
    p1.join()
    send('0' + bot.getResponse(msg, emb), broadcast=True)
    send('2' + bot.getKB(msg, emb), broadcast=True)
if __name__ == '__main__':
    emb = None
    p1 = Process(target=loadModel)
    p1.start()
    socketio.run(app)

Я запускаю процесс загрузки модели прямо перед запуском приложения (предпоследняя строка). Я присоединяюсь к процессу в функции handleMessage прямо перед тем, как мне нужно значение emb. Так что я могу получить доступ к emb вне функции loadModel, я объявил это прямо перед созданием процесса. Однако, когда я запускаю код, я получаю сообщение о том, что emb - это объект NoneType. Это похоже на проблему с областью видимости, но независимо от того, где я говорю emb = None, я получаю, что emb - это None или undefined, когда я пытаюсь его использовать. Как я могу загрузить модель в другой процесс, чем получить доступ к модели? Спасибо.

1 Ответ

0 голосов
/ 06 июля 2018

Вы не можете загрузить модель из другого процесса. Это не так, как работает мультиобработка.

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

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

Если вы хотите поэкспериментировать с потоками или процессами, я бы рекомендовал начать с более простых примеров.

Что касается вашей проблемы, я бы начал с попытки оптимизировать загрузочный код, чтобы он работал быстрее. Не зная, что он делает, трудно сделать более конкретные предложения.

...