[英]Transferring modules between two processes with python multiprocessing
所以我有问题。 我试图让我的导入更快,所以我开始使用多处理模块将一组导入拆分为两个函数,然后在单独的核心上运行每个函数,从而加快导入速度。 但是现在代码根本无法识别模块。 我究竟做错了什么 ?
import multiprocessing
def core1():
import wikipedia
import subprocess
import random
return wikipedia, subprocess, random
def core2():
from urllib import request
import json
import webbrowser
return request, json, webbrowser
if __name__ == "__main__":
start_core_1 = multiprocessing.Process(name='worker 1', target=core1, args = core2())
start_core_2 = multiprocessing.Process(name='worker 2', target=core2, args = core1())
start_core_1.start()
start_core_2.start()
while True:
user = input('[!] ')
with request.urlopen('https://api.wit.ai/message?v=20160511&q=%s&access_token=Z55PIVTSSFOETKSBPWMNPE6YL6HVK4YP' % request.quote(user)) as wit_api: # call to wit.ai api
wit_api_html = wit_api.read()
wit_api_html = wit_api_html.decode()
wit_api_data = json.loads(wit_api_html)
intent = wit_api_data['entities']['Intent'][0]['value']
term = wit_api_data['entities']['search_term'][0]['value']
if intent == 'info_on':
with request.urlopen('https://kgsearch.googleapis.com/v1/entities:search?query=%s&key=AIzaSyCvgNV4G7mbnu01xai0f0k9NL2ito8vY6s&limit=1&indent=True' % term.replace(' ', '%20')) as response:
google_knowledge_base_html = response.read()
google_knowledge_base_html = google_knowledge_base_html.decode()
google_knowledge_base_data = json.loads(google_knowledge_base_html)
print(google_knowledge_base_data['itemListElement'][0]['result']['detailedDescription']['articleBody'])
else:
print('Something')
我认为您错过了整个画面的重要部分,即您在使用multiprocessing
时需要了解的重要部分。
这里有一些你必须知道的关键部分,然后你就会明白为什么你不能只在子进程中导入模块并加快速度。 即使返回加载的模块也不是一个完美的答案。
首先,当您使用multiprocess.Process
,子进程会被forked
(在 Linux 上)或spawned
(在 Windows 上)。 我假设您使用的是 Linux。 在这种情况下,每个子进程都会从父进程(全局状态)继承每个加载的模块。 当子进程更改任何内容时,例如全局变量或导入新模块,这些内容仅保留在其上下文中。 所以,父进程不知道它。 我相信的一部分这也可以是兴趣。
其次,模块可以是一组类、外部库绑定、函数等,其中一些很可能不能被pickle,至少不能被pickle
。 这是可以在Python 2.7和Python 3.X 中腌制的列表。 甚至还有一些库可以为您提供“更多的酸洗能力”,例如dill 。 但是,我不确定酸洗整个模块是否是一个好主意,更不用说您的导入速度很慢,但您想序列化它们并将它们发送到父进程。 即使您设法做到了,这听起来也不是最好的方法。
关于如何改变视角的一些想法:
尝试修改您需要的模块,为什么? 也许您可以使用其他可以为您提供类似功能的模块。 也许这些模块过重并带来了太多,与您得到的相比,成本很高。
如果您的模块加载缓慢,请尝试制作一个始终运行的脚本,这样您就不必多次运行它。
如果你真的需要这些模块,也许你可以将它们分开使用在两个进程中,然后每个进程做它自己的事情。 例如,一个进程解析页面,其他进程处理等等。 这样你就加快了加载速度,但你必须处理进程之间的消息传递。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.