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

时间:2017-04-21 14:24:54

标签: python python-2.7 multiprocessing arcpy

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

例如:

multiprocessing

当你在IDLE中运行它时它根本就没有错误......只是继续进行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 检查(这样做不错,所以不是问题)。问题是当你在CMD终端(操作系统或Python)中运行它时会产生Queue未定义的错误!

只是一个奇怪的话题。

1 个答案:

答案 0 :(得分:3)

类似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