访问在多处理函数中分配的变量
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 线程可以 运行。
如果您想尝试线程或进程,我建议您从更简单的示例开始。
至于你的问题,我会首先尝试优化加载代码,使其更快。不知道它做了什么,很难提出更具体的建议。
我正在制作一个网站,在启动时,我想启动另一个开始加载嵌入模型的进程,因为这需要很长时间并且最终会被用户需要。这是我的代码:
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 线程可以 运行。
如果您想尝试线程或进程,我建议您从更简单的示例开始。
至于你的问题,我会首先尝试优化加载代码,使其更快。不知道它做了什么,很难提出更具体的建议。