在 Python 中使用多处理,导入语句的正确方法是啥?

Posted

技术标签:

【中文标题】在 Python 中使用多处理,导入语句的正确方法是啥?【英文标题】:Using multiprocessing in Python, what is the correct approach for import statements?在 Python 中使用多处理,导入语句的正确方法是什么? 【发布时间】:2016-04-09 17:31:18 【问题描述】:

PEP 8 状态:

导入总是放在文件的顶部,就在任何模块 cmets 和文档字符串之后,模块全局变量和常量之前。

但是,如果我正在导入的类/方法/函数仅由子进程使用,那么在需要时进行导入肯定会更有效吗?我的代码基本上是:

p = multiprocessing.Process(target=main,args=(dump_file,))
p.start()
p.join()
print u"Process ended with exitcode: ".format(p.exitcode)
if os.path.getsize(dump_file) > 0:
    blc = BugLogClient(listener='http://21.18.25.06:8888/bugLog/listeners/bugLogListenerREST.cfm',appName='main')
    blc.notifyCrash(dump_file)

main() 是主应用程序。此功能需要大量导入才能运行,并且会占用一些 ram 空间(+/- 35MB)。当应用程序在另一个进程中运行时,导入在 PEP 8 之后进行了两次(一次由父进程执行,另一次由子进程执行)。还应该注意的是,这个函数应该只被调用一次,因为父进程正在等待查看应用程序是否崩溃并留下退出代码(感谢故障处理程序)。所以我在主函数中编写了这样的导入代码:

def main(dump_file):

    import shutil
    import locale

    import faulthandler

    from PySide.QtCore import Qt
    from PySide.QtGui import QApplication, QIcon

代替:

import shutil
import locale

import faulthandler

from PySide.QtCore import Qt
from PySide.QtGui import QApplication, QIcon

def main(dump_file):

是否有一种“标准”方式来处理使用多处理完成的导入?

PS:我看过这个sister question

【问题讨论】:

将导入放在顶部,遵循 PEP 8 您如何知道您建议的方法节省了多少内存? 我可以使用 windows 任务管理器查看每个进程占用多少内存。按照我提出的方法,父进程需要 6Mb,而按照 PEP 8,它需要 36Mb。 这很尴尬。是的,你又是对的,我的“解决方案”根本无济于事。也许来得太晚了,如果我有一个可行的想法,我会回来的:) 在 unixy 系统上,multiprocessing 是一个廉价的fork,其中子级拥有父级空间的写入时复制视图。没有重新导入任何内容,并且“顶部导入”规则是有意义的。在 Windows 中,multiprocessing 需要腌制环境并在子进程空间中重建它。即使不是完全 pep8,减少进口也很有意义。无论如何,它是一个黑客......所以在你的代码中继续这个传统! 【参考方案1】:

“标准”方式是 PEP 8 报告的方式。这就是 PEP 8 的用途:Python 编码参考指南。

虽然总是有例外。本案就是其中之一。

由于 Windows 不会克隆父进程的内存,因此当生成子进程时,子进程必须重新导入所有模块。 Linux 以更优化的方式处理进程,避免了此类问题。

我不熟悉 Windows 内存管理,但我会说模块是共享的,不会加载两次。您可能看到的是两个进程的虚拟内存,而不是物理内存。在物理内存上,只应加载一份模块副本。

是否遵循 PEP 8 由您决定。当资源受到限制时,代码需要适应。但如果没有必要,不要过度优化代码!这是错误的做法。

【讨论】:

以上是关于在 Python 中使用多处理,导入语句的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

使用 pytest 正确导入

如何在多目录项目中正确导入 python 模块?

如何从python中的方法执行全局from foo import bar?

PyQt - 导入语句的正确位置

python中如何导入gdal包?

如何防止多处理继承导入和全局?