问题 Python 2.7 concurrent.futures.ThreadPoolExecutor没有并行化


我在基于Intel i3的机器上运行以下代码,该机器具有4个虚拟内核(2个超线程/物理内核,64位)和安装的Ubuntu 14.04:

n = multiprocessing.cpu_count()
executor = ThreadPoolExecutor(n)
tuple_mapper = lambda i: (i, func(i))
results = dict(executor.map(tuple_mapper, range(10)))

代码似乎没有以并行方式执行,因为CPU的使用率仅为25%。在利用率图表中,一次仅100%使用4个虚拟核心中的一个。使用的核心每10秒左右交替一次。

但是并行化在具有相同软件设置的服务器计算机上运行良好。我不知道核心的确切数量和确切的处理器类型,但我确信它有几个核心并且利用率为100%并且计算速度快(使用并行化后速度提高了10倍)一些实验用它)。

我希望,并行化也可以在我的机器上运行,而不仅仅是在服务器上。

为什么不起作用?它与我的操作系统设置有关吗?我必须改变它们吗?

提前致谢!

更新: 有关背景信息,请参阅下面的正确答案。为了完整起见,我想提供一个解决问题的示例代码:

tuple_mapper = lambda i: (i, func(i))
n = multiprocessing.cpu_count()
with concurrent.futures.ProcessPoolExecutor(n) as executor:
    results = dict(executor.map(tuple_mapper, range(10)))

在重复使用之前,请注意您正在使用的所有函数都在模块的顶层定义,如下所述: Python多处理酸洗错误


2050
2018-05-21 16:05


起源

尝试一下 ProcessPoolExecutor。可能是 GIL。 - kichik
有趣的是,但是由于它具有相同的软件软件设置,因此服务器显示100%利用率而不使用并行化的事实我仍然感到恼火。我会试试你的意见。 - Gerhard Hagerer


答案:


听起来你正在看到Python的结果 全球口译员锁 (a.k.a GIL)。

在CPython中,全局解释器锁(GIL)是一个互斥锁    防止多个本机线程 从执行Python字节码   一旦。

由于所有线程都运行纯Python代码,因此其中只有一个可以并行运行。这应该只会导致一个CPU处于活动状态并与您对问题的描述相匹配。

你可以通过使用多个进程来解决它 ProcessPoolExecutor 来自同一个模块。其他解决方案包括切换到没有GIL的Jython或IronPython。

ProcessPoolExecutor类是使用池的Executor子类   进程异步执行调用。 ProcessPoolExecutor使用   多处理模块, 这使得它可以支持Global   口译员锁 但也意味着只有可选择的对象才可以   执行并返回。


14
2018-05-21 16:16



谢谢,现在我的CPU使用率达到了100%!在解决这个问题的过程中,我还必须解决以下错误: stackoverflow.com/questions/8804830/... - Gerhard Hagerer
为什么不pypy?我相信pypy也免于GIL。 - 0xc0de
@ 0xc0de PyPy仍然根据它的GIL 常问问题 - kichik
谢谢你纠正,我的坏,一个愚蠢的确实。 - 0xc0de
我的Jupyter笔记本中的Python 3.5有这个问题需要切换到 ProcessPoolExecutor 也是为了看到100%的CPU使用率 - 这是由于同样的原因吗? - Stefan Falk