skj*_*rns 6 python python-multiprocessing
众所周知,我们需要使用Python 来保护main()运行时代码.multiprocessingif __name__ == '__main__'
我理解在某些情况下这是必要的,以提供对main中定义的函数的访问,但我不明白为什么在这种情况下这是必要的:
file2.py
import numpy as np
from multiprocessing import Pool
class Something(object):
def get_image(self):
return np.random.rand(64,64)
def mp(self):
image = self.get_image()
p = Pool(2)
res1 = p.apply_async(np.sum, (image,))
res2 = p.apply_async(np.mean, (image,))
print(res1.get())
print(res2.get())
p.close()
p.join()
Run Code Online (Sandbox Code Playgroud)
main.py
from file2 import Something
s = Something()
s.mp()
Run Code Online (Sandbox Code Playgroud)
Something工作所需的所有功能或进口都是其中的一部分file2.py.为什么子流程需要重新运行main.py?
我认为__name__解决方案不是很好,因为这阻止我分发代码,file2.py因为我不能确保他们保护他们的主要.Windows没有解决方法吗?如何解决这个问题(因为我从来没有遇到任何问题,没有用任何软件包来保护我的主程序 - 他们只是不使用多处理?)
编辑:
我知道这是因为fork()Windows中没有实现.我只是问是否有一个黑客让翻译开始,file2.py而不是main.py因为我可以肯定这file2.py是自给自足的
使用“ spawn”启动方法时,新进程是从头开始的Python解释器。子流程中的新Python解释器无法确定需要导入哪些模块,因此它们会再次导入主模块,从而又将导入其他所有模块。这意味着必须可以导入主模块而没有任何副作用。
如果您使用的平台不同于Windows,则可以使用“ fork”启动方法,而不会出现此问题。
也就是说,使用有什么问题if __name__ == "__main__":?它还有很多其他好处,例如,文档工具将能够处理您的主模块,并且单元测试更加容易等,因此您在任何情况下都应使用它。
主模块已导入(但__name__ != '__main__'由于 Windows 试图在没有分叉的系统上模拟类似分叉的行为)。multiprocessing无法知道您没有在主模块中执行任何重要操作,因此“以防万一”进行导入以创建与主进程中类似的环境。如果不这样做,则 main 中的副作用所发生的各种事情(例如导入、具有持久副作用的配置调用等)可能无法在子进程中正确执行。
因此,如果他们不保护自己的__main__,则代码就不是多处理安全的(也不是单元测试安全、导入安全等)。保护性包装if __name__ == '__main__':应该是所有正确主模块的一部分。继续分发它,并附上有关需要多处理安全主模块保护的注释。