多处理代码在导入时工作,在被调用时中断

Multiprocessing code works upon import, breaks upon being called

在一个名为 test.py 的文件中,我有

print 'i am cow'
import multi4
print 'i am cowboy'

multi4.py我有

import multiprocessing as mp
manager = mp.Manager()
print manager

我对这段代码的运行方式感到困惑。

在命令行中,如果我键入 python,然后在 python 环境中,如果我键入 import test.py,我会得到预期的行为:

Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information.

>>>import test
i am cow
<multiprocessing.managers.SyncManager object at 0x025209B0>
i am cowboy 
>>>

但是,如果我在命令行输入 test.py,我会得到

i am cow
i am cow
i am cow
i am cow
i am cow
i am cow
i am cow
i am cow
i am cow
i am cow
i am cow
i am cow
i am cow
i am cow
i am cow
i am cow
i am cow
i am cow

除非我杀死它,否则它可能会永远持续下去。当我杀死它时,我得到了一堆重复的错误:

KeyboardInterrupt
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Python27\lib\multiprocessing\forking.py", line 373, in main
    prepare(preparation_data)
  File "C:\Python27\lib\multiprocessing\forking.py", line 488, in prepare
    '__parents_main__', file, path_name, etc
KeyboardInterrupt
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Python27\lib\multiprocessing\forking.py", line 373, in main
    prepare(preparation_data)
  File "C:\Python27\lib\multiprocessing\forking.py", line 488, in prepare
    '__parents_main__', file, path_name, etc
KeyboardInterrupt

所以这是怎么回事?为什么它在导入时表现出一种方式,而当我尝试 运行 它时表现出另一种方式?

multiprocessing won't work properly 在 Windows 的交互提示中,因为它不能在 child 进程中正确地 re-import __main__它产卵。然而,这实际上 帮助 你在这里,因为它防止 manager = mp.Manager() 行在 Manager 时产生的 child 进程中递归执行启动。

然而,在实际脚本中,child 可以 re-import __main__ 正确。您看到了无限递归,因为您没有使用 if __name__ == "__main__": 保护来保护对 mp.Manager() 的调用,这是 required on Windows 以防止 mp.Manager() 在 child 当 re-import 发生时:

import multiprocessing as mp
if __name__ == "__main__":
    manager = mp.Manager()
    print manager

编辑:

在您的示例中,您的主脚本 (test.py) 导入了创建 Manager 的模块,需要进行一些重构。您需要通过调用模块中实际使用 multiprocessing:

的方法从主脚本实例化 Manager
print 'i am cow'
import multi4
if __name__ == "__main__":
    multi4.init_manager()
print 'i am cowboy'

multi4.py

import multiprocessing as mp
manager = None
def init_manager():
    global manager
    manager = mp.Manager()

这是确保仅在实际执行脚本时才创建 Manager 的唯一方法。