我正在使用Pool
软件包(multiprocessing
)中的from multiprocessing.dummy import Pool
。
我编写了一个函数,该函数读取文本文件并对其进行预处理,以供将来使用。
我大约有20,000个这样的文本文件,因此我想并行化进程,为此我使用了池。
我在运行代码的远程服务器上有32个内核,因此我尝试打开70个进程(我也尝试了较少,问题仍然存在)-这就是我的系统监视器的样子:
正如人们所见,32个内核中有16个根本不工作!
任何帮助将不胜感激。
答案 0 :(得分:1)
正如我在评论中所说,所有multiprocessing.dummy
结构都旨在使用常规线程来模拟多处理接口,这对于测试,调试,概要分析等非常有用。或者,如官方文档所述:>
multiprocessing.dummy
复制了multiprocessing
的API,但仅不过是threading
模块周围的包装器。
尽管Python(CPython)threading
使用实际的系统线程,因此从理论上讲,可以使线程代码在不同的CPU上执行,由于可怕的GIL,这些线程中不会有两个同时运行。该规则是有例外的,例如,所有抽象系统调用并等待事件(例如I / O)的任务都可以并行执行,但是当处理移至Python域时,它将被GIL锁定,并且不会允许继续执行,直到选择代码计数器切换其上下文为止。
长话短说,如果您想通过multiprocessing
池使用多个内核,请不要使用multiprocessing.dummy
中的改编和抽象(对于其他dummy
包来说, ),并使用根multiprocessing
模块本身-在您的情况下为multiprocessing.pool.Pool
。
话虽这么说,鉴于threading
模块不带有池接口,所以我经常发现我自己使用multiprocessing.dummy.Pool
(或multiprocessing.pool.ThreadPool
)代替了繁琐的I / O操作(即不受GIL的限制),当共享内存比 shared 处理及其带来的开销更为重要时。即使在切换到multiprocessing.pool.Pool
的情况下,如果在抓取文件时不进行繁重的后处理,您也不会注意到很大的不同。