繁体   English   中英

为什么'__main__'中的导入模块不允许multiprocessig使用模块?

[英]Why does importing module in '__main__' not allow multiprocessig to use module?

我已经通过将导入移动到顶部声明来解决了我的问题,但它让我想知道:为什么我不能在multiprocessing目标函数中使用在'__main__'中导入'__main__'

例如:

import os
import multiprocessing as mp

def run(in_file, out_dir, out_q):
    arcpy.RaterToPolygon_conversion(in_file, out_dir, "NO_SIMPIFY", "Value")
    status = str("Done with "+os.path.basename(in_file))
    out_q.put(status, block=False)

if __name__ == '__main__':
    raw_input("Program may hang, press Enter to import ArcPy...")
    import arcpy

    q = mp.Queue()
    _file = path/to/file
    _dir = path/to/dir
    # There are actually lots of files in a loop to build
    # processes but I just do one for context here
    p = mp.Process(target=run, args=(_file, _dir, q))
    p.start()

# I do stuff with Queue below to status user

当你在IDLE中运行它时它根本就没有错误...只是继续进行Queue检查(这样做不错,所以不是问题)。 问题是当你在CMD终端(操作系统或Python)中运行它时会产生错误,即没有定义arcpy

只是一个奇怪的话题。

unix类系统和Windows的情况不同。 在unixy系统上, multiprocessing使用fork来创建共享父内存空间的写时复制视图的子进程。 孩子看到来自父母的导入,包括父项导入的任何内容, if __name__ == "__main__":

在Windows上,没有fork,必须执行新进程。 但只是重新运行父进程不起作用 - 它将再次运行整个程序。 相反, multiprocessing运行其自己的python程序,该程序导入父主脚本,然后对父对象空间的视图进行pickle / unpickles,希望这对父进程足够。

该方案是__main__子进程和__main__父脚本不会运行的。 主脚本刚刚像任何其他模块一样导入。 原因很简单:运行父__main__只会再次运行完整的父程序, mp必须避免。

这是一个测试,以显示正在发生的事情。 一个名为testmp.py的主模块和第一个导入的第二个模块test2.py

testmp.py

import os
import multiprocessing as mp

print("importing test2")
import test2

def worker():
    print('worker pid: {}, module name: {}, file name: {}'.format(os.getpid(), 
        __name__, __file__))

if __name__ == "__main__":
    print('main pid: {}, module name: {}, file name: {}'.format(os.getpid(), 
        __name__, __file__))
    print("running process")
    proc = mp.Process(target=worker)
    proc.start()
    proc.join()

test2.py

import os

print('test2 pid: {}, module name: {}, file name: {}'.format(os.getpid(),
        __name__, __file__))

在Linux上运行时,test2将导入一次,并且worker将在主模块中运行。

importing test2
test2 pid: 17840, module name: test2, file name: /media/td/USB20FD/tmp/test2.py
main pid: 17840, module name: __main__, file name: testmp.py
running process
worker pid: 17841, module name: __main__, file name: testmp.py

在Windows下,注意“导入test2”打印两次 - testmp.py运行两次。 但是“主要的pid”只打印一次 - 它的__main__没有运行。 这是因为multiprocessing在导入期间将模块名称更改为__mp_main__

E:\tmp>py testmp.py
importing test2
test2 pid: 7536, module name: test2, file name: E:\tmp\test2.py
main pid: 7536, module name: __main__, file name: testmp.py
running process
importing test2
test2 pid: 7544, module name: test2, file name: E:\tmp\test2.py
worker pid: 7544, module name: __mp_main__, file name: E:\tmp\testmp.py

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM