使用多处理时,在窗口中强制使用if __name __ ==“__ main__”

时间:2013-12-03 20:09:57

标签: python windows multiprocessing

在Windows上的python中使用多处理时,应该保护程序的入口点。 文档说“确保新的Python解释器可以安全地导入主模块,而不会导致意外的副作用(例如启动新进程)”。任何人都能解释这究竟是什么意思吗?

2 个答案:

答案 0 :(得分:16)

对你已经得到的好答案进行了一些扩展,如果你了解Linux-y系统的功能,它会有所帮助。他们使用fork()生成新流程,其中有两个良好的后果:

  1. 主程序中存在的所有数据结构对子进程可见。他们实际上处理数据的副本
  2. 子进程在主程序中fork()之后的指令处开始执行 - 因此模块中已执行的任何模块级代码都不会再次执行。
  3. 在Windows中无法使用

    fork(),因此在Windows上,每个子进程都会重新导入每个模块。所以:

    1. 在Windows上,子程序可以看到主程序中存在的 no 数据结构;和,
    2. 所有模块级代码都在每个子进程中执行。
    3. 所以你需要考虑一下你只想在主程序中执行哪些代码。最明显的例子是,您希望创建子进程的代码仅在主程序中运行 - 因此应受__name__ == '__main__'保护。对于一个更微妙的示例,请考虑构建一个巨大的列表的代码,您打算将其传递给工作进程以进行爬网。你可能也希望保护它,因为在这种情况下没有必要让每个工作进程浪费RAM和时间来构建他们自己无用的巨大列表副本。

      请注意,即使在Linux-y系统上使用__name__ == "__main__"也是一个好主意,因为它使预期的工作分工更清晰。并行程序可能会令人困惑 - 每一点都有帮助; - )

答案 1 :(得分:9)

multiprocessing模块的工作原理是创建将导入模块的新Python进程。如果您没有添加__name__== '__main__'保护,那么您将进入一个永无止境的新流程创建循环。它是这样的:

  • 您的模块已导入并在导入期间执行代码,导致multiprocessing生成4个新进程。
  • 这4个新进程依次导入模块并在导入期间执行代码,导致multiprocessing生成16个新进程。
  • 这16个新进程依次导入模块并在导入期间执行代码,导致multiprocessing生成64个新进程。
  • 嗯,希望你能得到这张照片。

所以我们的想法是确保生成的过程只发生一次。这可以通过__name__== '__main__'保护的惯用法轻松实现。