代码如下。当我将其复制并粘贴到我的cmd提示符中时,它会抛出'module'对象没有属性'func',但当我将其保存为 .py 文件时并执行python test.py
,它只是工作正常。
import multiprocessing
import time
def func(msg):
for i in xrange(3):
print msg
time.sleep(1)
if __name__ == '__main__':
pool = multiprocessing.Pool(processes=4)
for i in xrange(5):
msg = "hello %d" %(i)
pool.apply_async(func, (msg, ))
pool.close()
pool.join()
print "Sub-process(es) done."
在运行python代码时,有没有人能给我一个关于提示符和文件之间区别的解释?非常感谢!
答案 0 :(得分:6)
这种情况正在发生,因为在Windows上,func
需要被腌制并通过IPC发送到子进程。为了让孩子解开func
,它需要能够从父的__main__
模块中导入它。当在普通Python脚本中发生这种情况时,子进程可以重新导入您的脚本,__main__
将包含在脚本顶层声明的所有函数,因此它可以正常工作。但是,在交互式解释器中,您在解释器中定义的函数不能简单地从正常脚本中的文件中重新导入,因此它们不位于{{1}在孩子身上。如果您直接使用__main__
重新创建问题,则会更清楚:
multiprocessing.Process
这样,>>> def f():
... print "HI"
...
>>> import multiprocessing
>>> p = multiprocessing.Process(target=f)
>>> p.start()
>>> Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\python27\lib\multiprocessing\forking.py", line 381, in main
self = load(from_parent)
File "C:\python27\lib\pickle.py", line 1378, in load
return Unpickler(file).load()
File "C:\python27\lib\pickle.py", line 858, in load
dispatch[key](self)
File "C:\python27\lib\pickle.py", line 1090, in load_global
klass = self.find_class(module, name)
File "C:\python27\lib\pickle.py", line 1126, in find_class
klass = getattr(mod, name)
AttributeError: 'module' object has no attribute 'f'
无法找到模块就更清楚了。如果您向pickle
添加一些跟踪,则可以看到pickle.py
指的是'module'
:
__main__
再次使用额外的print语句重新运行相同的代码会产生以下结果:
def load_global(self):
module = self.readline()[:-1]
name = self.readline()[:-1]
print("module {} name {}".format(module, name)) # I added this.
klass = self.find_class(module, name)
self.append(klass)
值得注意的是,此示例在Posix平台上实际上运行正常,因为module multiprocessing.process name Process
module __main__ name f
< same traceback as before>
用于生成子进程,这意味着在创建os.fork()
之前定义的任何函数都将在孩子的Pool
模块。因此,虽然上面的示例可行,但是这个仍然会失败,因为在创建__main__
之后定义了worker函数(这意味着在调用Pool
之后):< / p>
os.fork()