【问题标题】:Transferring modules between two processes with python multiprocessing使用 python 多处理在两个进程之间传输模块
【发布时间】:2018-02-25 15:01:56
【问题描述】:

所以我有一个问题。我试图让我的导入更快,所以我开始使用多处理模块将一组导入分成两个函数,然后在单独的核心上运行每个函数,从而加快导入速度。但是现在代码根本无法识别模块。我做错了什么?

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')

【问题讨论】:

  • 您面临的确切错误/问题是什么?尝试详细描述您的问题。
  • @Reck 我收到 TypeError: can't pickle module objects 错误,您可以在下图中看到。 prntscr.com/ijkm0x
  • 这应该在问题中提到/添加。以便更容易理解确切的问题。
  • 通过错误消息我可以推断出来。您作为 args 传递的模块实例被馈送到多处理进程。这些进程使用 pickle 来存储进程转储。这里的问题是 pickle module 不能 pickle 模块对象。请缩进你的代码。
  • 你可能想check this一次。

标签: python multiprocessing


【解决方案1】:

我认为您错过了整个图片的重要部分,即在使用 multiprocessing 时需要了解的关键部分。

这里有一些你必须知道的关键部分,然后你就会明白为什么你不能只在子进程中导入模块并加快速度。即使返回加载的模块也不是一个完美的答案。

首先,当您使用multiprocess.Process 时,子进程是forked(在Linux 上)或spawned(在Windows 上)。我假设您使用的是 Linux。在这种情况下,每个子进程都会从父进程(全局状态)继承每个加载的模块。当子进程更改任何内容时,例如全局变量或导入新模块,它们只会保留在其上下文中。因此,父进程不知道它。我相信this 的一部分也可以引起人们的兴趣。

其次,模块可以是一组类、外部库绑定、函数等,其中一些很可能无法腌制,至少在pickle 中是这样。这是Python 2.7Python 3.X 中可以腌制的内容列表。甚至还有像dill 这样的库可以为您提供“更多的酸洗能力”。但是,我不确定腌制整个模块是不是一个好主意,更不用说你的导入速度很慢,但你想序列化它们并将它们发送到父进程。即使您设法做到了,这听起来也不是最好的方法。

关于如何改变视角的一些想法:

  1. 尝试修改您需要的模块,为什么?也许您可以使用可以为您提供类似功能的其他模块。也许这些模块过重,带来了太多的东西,与你得到的相比,成本很高。

  2. 如果您的模块加载缓慢,请尝试制作一个始终运行的脚本,这样您就不必多次运行它。

  3. 如果你真的需要这些模块,也许你可以将它们分开在两个进程中使用,然后每个进程都做自己的事情。例如,一个进程解析页面,其他进程进程等等。这样可以加快加载速度,但必须处理进程之间的消息传递。

【讨论】:

  • 实际上我使用的是 Windows,但这个建议实际上很有用。谢谢。
猜你喜欢
  • 1970-01-01
  • 2017-12-12
  • 2014-04-16
  • 1970-01-01
  • 2016-06-13
  • 2018-11-29
  • 2020-06-25
  • 2020-04-25
  • 1970-01-01
相关资源
最近更新 更多