【问题标题】:Python dynamic module loading with multiprocessing使用多处理的 Python 动态模块加载
【发布时间】:2018-04-12 22:08:17
【问题描述】:

如果模块“user.py”与代码位于同一目录中,则以下代码有效,但如果位于不同目录中,则失败。我收到的错误消息是“ModuleNotFoundError: No module named 'user'

import multiprocessing as mp
import imp

class test():
    def __init__(self,pool):

        pool.processes=1
        usermodel=imp.load_source('user','D:\\pool\\test\\user.py').userfun
         #file D:\\pool\\test\\user.py looks like this:
         #   def userfun():
         #      return 1

         vec=[]
         for i in range(10):
            vec.append([usermodel,i])

         pool.map(self.myfunc,vec)

    def myfunc(self,A):
        userfun=A[0]
        i=A[1]
        print (i,userfun())
        return

if __name__=='__main__':
    pool=mp.Pool()
    test(pool)

如果函数 myfunc 在没有池化进程的情况下调用,则无论 user.py 是在主代码的同一目录中还是在 \test 中,代码都可以。为什么池化进程在单独的目录中找不到 user.py?我尝试了不同的方法,例如修改我的路径然后导入用户和 importlib,结果都相同。

我使用的是 Windows 7 和 python 3.6

【问题讨论】:

  • 试试open('D:\\pool\\test\\user.py', 'r').close()。你有任何错误吗?
  • 首先,您使用的是哪个版本的 Python? (而且,如果不是 2.7 或 3.3,你为什么使用imp?)
  • 其次,给我们完整的回溯,而不仅仅是错误信息。
  • 无论如何,我无法在 3.6 中重现此问题。在 2.7 中,我必须进行各种更改才能达到这一点——首先你不能将self.myfunc 传递给Pool.map,因为它不能被腌制。一旦我修复了所有这些,它基本上和self.myfunc一样的问题——user.userfun也不能被腌制。
  • @smac89 - 尝试打开和关闭文件时没有错误。

标签: python multiprocessing imp


【解决方案1】:

multiprocessing 试图假装它就像threading,但抽象像筛子一样泄漏。它泄露的一种方式是,与工作进程的通信涉及很多隐式酸洗和数据复制。

当您尝试将usermodel 发送给工作人员时,multiprocessing 隐式腌制它并尝试让工作人员解开腌制。通过记录模块名称和函数名称来腌制函数,因此工作人员只是认为应该执行from user import userfun 来访问userfun。它不知道user需要从特定文件系统位置加载imp.load_source,所以它无法重构usermodel

这个问题的表现方式是依赖于操作系统的,因为如果多处理使用 fork 启动方法,worker 会从主进程继承 user 模块。 fork 在 Unix 上是默认的,但在 Windows 上不可用。

【讨论】:

    猜你喜欢
    • 2010-10-20
    • 2010-10-31
    • 1970-01-01
    • 2012-05-08
    • 2015-08-26
    • 2011-04-04
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多