如果你觉得CSDN上都是垃圾,那就去建设它
前两天的bug了,具体报错信息可以参考:这里。
一言以蔽之,我的情况是因为用pycharm的python console, 也就是交互式的解释器运行了带有multiprocessing的代码,改下配置取消run with python console选项即可。
具体情况描述:我自己的代码没有调用pickle,但是还是出了这个问题,所以并不是网上说的空文件的问题。结合报错位置,以及以下情况:(1)我的代码改成并行之前正常运行,一加multiprocessing就报了这个错;(2) debug模式代码可以运行,但是run模式不行,确定了是python console + multiprocessing的问题。
那么,为什么会产生这个bug呢?
来看官方文档的解释:
The
__main__
module must be importable by worker subprocesses. This means that ProcessPoolExecutor will not work in the interactive interpreter.
具体原因知乎上有个解释(虽然估计是官方文档吧):
windows系统下,解释器是通过多次import the calling module来实现多进程的,这也就解释了各种教程里为什么都会强调要把multiprocessing的语句放到__main__
里。而交互式的__main__
函数是not importable的。
Since Windows has no fork, the multiprocessing module starts a new Python process and imports the calling module. If Process() gets called upon import, then this sets off an infinite succession of new processes (or until your machine runs out of resources). This is the reason for hiding calls to Process() inside
作者:黄哥
链接:https://www.zhihu.com/question/47925001/answer/108232689
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
此前,而我只知道pickle库可以存变量,那multiprocessing的问题又和pickle有啥关系呢?查了资料,我们在import时,实际发生了这些事情:
在python中使用import语句导入模块时,python通过三个步骤来完成这个行为。
1:在python模块加载路径中查找相应的模块文件
2:将模块文件编译成中间代码
3:执行模块文件中的代码
这两个问题的联系应该就在于2.编译成中间代码(.pyc文件)这一步。
所以,我个人猜测是:
pickle是用来读import时编译生成的.pyc文件的,如果我们的__main__
不能被import的话,当然也就没有.pyc文件给我们读了,所以读的时候就会报错了。官方文档有一段描述也能佐证:
The ProcessPoolExecutor class is an Executor subclass that uses a pool of processes to execute calls asynchronously. ProcessPoolExecutor uses the multiprocessing module, which allows it to side-step the Global Interpreter Lock but also means that only picklable objects can be executed and returned.
如果有不正确的地方,欢迎指正!