访问在多进程函数中分配的变量

时间:2018-07-05 22:43:07

标签: python multiprocessing python-multiprocessing

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

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要么未定义。如何在不同的过程中加载模型然后访问模型?谢谢。

1 个答案:

答案 0 :(得分:1)

您不能从其他过程加载模型。那不是多重处理的工作原理。

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

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

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

对于您的问题,我将从尝试优化加载代码开始,以便更快。不知道该怎么做,很难提出更具体的建议。