访问在多处理函数中分配的变量

Accessing a variable assigned in multiprocessed function

我正在制作一个网站,在启动时,我想启动另一个开始加载嵌入模型的进程,因为这需要很长时间并且最终会被用户需要。这是我的代码:

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)

我在开始 运行 应用程序之前就开始了加载模型的过程(倒数第二行)。在我需要 emb 的值之前,我在 handleMessage 函数中加入了进程。为了可以在 loadModel 函数之外访问 emb,我在创建进程之前就声明了它。但是,当我 运行 代码时,我收到一条错误消息,指出 emb 是一个 NoneType 对象。这似乎是一个范围界定问题,但无论我在哪里说 emb = None,当我尝试使用它时,我要么得到 emb 是 None 或未定义。如何在不同的进程中加载​​模型然后访问模型?谢谢。

您不能从不同的进程加载模型。这不是多处理的工作方式。

在分叉处,每个进程都有自己的内存副本(概念上;实际上有一些技巧可以防止复制所有内容)。 fork 后变量的任何更改只会在更改它的进程中可见,而不在其父进程中可见。

如果你想共享内存你需要使用线程,而不是进程。但是以安全的方式改变线程之间共享的内存是相当复杂的。无论如何,它可能对你没有太大帮助,因为 Python 有一个全局解释器锁:一次只有一个 Python 线程可以 运行。

如果您想尝试线程或进程,我建议您从更简单的示例开始。

至于你的问题,我会首先尝试优化加载代码,使其更快。不知道它做了什么,很难提出更具体的建议。