博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python在windows环境多进程(multiprocessing)报错The "freeze_support()" line can be omitted
阅读量:4300 次
发布时间:2019-05-27

本文共 2921 字,大约阅读时间需要 9 分钟。

记得刚学Python的时就碰到过这个问题,结果快一年后再看仍然不能完全理解,简单做个记录,日后再补充。

下面代码会报错:

import multiprocessingimport timedef sing():    print('ing')    time.sleep(1)# if __name__ == '__main__':#如果下面代码不被# if __name__ == '__main__':包裹的话,就会报错pool=multiprocessing.Pool(2)pool.apply(sing)for i in range(5):    pool.apply(sing)

 报错信息:

RuntimeError: 

        An attempt has been made to start a new process before the
        current process has finished its bootstrapping phase.

        This probably means that you are not using fork to start your

        child processes and you have forgotten to use the proper idiom
        in the main module:

            if __name__ == '__main__':

                freeze_support()
                ...

        The "freeze_support()" line can be omitted if the program

        is not going to be frozen to produce an executable.

简单翻译下:

RuntimeError:

  在当前进程完成了他的引导阶段之前试图去启动一个新进程。

  这可能是表示你没有用fork方法启动子进程,并且你忘了用正确的姿势在main模块中:

  if __name__ == '__main__':

                freeze_support()
                ...

如果程序不会被冻结以生成可执行文件The "freeze_support()" 这行代码可以被忽略

先说解决方法:

代码放在 if __name__ == '__main__':下执行就行了,如下:

import multiprocessingimport timedef sing():    print('ing')    time.sleep(1)if __name__ == '__main__':    pool=multiprocessing.Pool(2)    pool.apply(sing)    for i in range(5):        pool.apply(sing)

 至于具体为什么,根本原因,查看半天资料也没完全理解,大致就是windows创建进程没有fork方法,默认是spawn,而linux创建进程默认是fork方法。为了什么进程保护,代码必须放在if __name__ == '__main__':下面。想要完全理解估计还要深入理解进程的概念,什么僵尸进程,孤儿进程类似的吧。

 

官方文档:

Safe importing of main module 

Make sure that the main module can be safely imported by a new Python interpreter without causing unintended side effects (such a starting a new process).

For example, using the spawn or forkserver start method running the following module would fail with a :

from multiprocessing import Processdef foo():    print('hello')p = Process(target=foo)p.start()

Instead one should protect the “entry point” of the program by using if __name__ == '__main__': as follows:

from multiprocessing import Process, freeze_support, set_start_methoddef foo():    print('hello')if __name__ == '__main__':    freeze_support()    set_start_method('spawn')    p = Process(target=foo)    p.start()

(The freeze_support() line can be omitted if the program will be run normally instead of frozen.)

This allows the newly spawned Python interpreter to safely import the module and then run the module’s foo() function.

Similar restrictions apply if a pool or manager is created in the main module.

有道翻译一下:

确保新的Python解释器可以安全地导入主模块,而不会引起意外的副作用(这样就可以启动一个新进程)。

例如,使用spawn或forkserver start方法运行以下模块会失败,报错:RuntimeError:

相反,应该使用if……name__ == ' _main__'来保护程序的“入口点”:

(如果程序将正常运行而不是冻结,则可以省略freeze_support()行。)

这允许新生成的Python解释器安全地导入模块,然后运行模块的foo()函数。

如果在主模块中创建池或管理器,也会应用类似的限制。

stackoverflow:

On Windows the subprocesses will import (i.e. execute) the main module at start. You need to insert an if __name__ == '__main__': guard in the main module to avoid creating subprocesses recursively.

在windows系统中在最初的时候子进程会导入main模块,你需要插入if __name__ == '__main__',保护main模块为了避免递归的创建子进程。

暂时也就理解成这样,欢迎大佬指点

转载地址:http://vcxws.baihongyu.com/

你可能感兴趣的文章
Activiti工作流会签三 撤销,审批,驳回
查看>>
Oauth2方式实现单点登录
查看>>
CountDownLatch源码解析加流程图详解--AQS类注释翻译
查看>>
ES相关度评分
查看>>
我们一起做一个可以商用的springboot脚手架
查看>>
idea在搭建ssm框架时mybatis整合问题 无法找到mapper
查看>>
java设计基本原则----单一职责原则
查看>>
HashMap的实现
查看>>
互斥锁 synchronized分析
查看>>
java等待-通知机制 synchronized和waity()的使用实践
查看>>
win10 Docke安装mysql8.0
查看>>
docker 启动已经停止的容器
查看>>
order by 排序原理及性能优化
查看>>
Lock重入锁
查看>>
docker安装 rabbitMq
查看>>
git 常用命令 入门
查看>>
linux安装docker
查看>>
关闭selinx nginx无法使用代理
查看>>
shell 脚本部署项目
查看>>
spring cloud zuul网关上传大文件
查看>>