首页 文章

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

提问于
浏览
11

我在基于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倍)一些实验用它) .

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

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

提前致谢!

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

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 multiprocessing pickling error

1 回答

  • 14

    这听起来像你're seeing the results of Python'(a.k.a GIL) .

    在CPython中,全局解释器锁或GIL是一个互斥锁,它可以防止多个本机线程一次执行Python字节码 .

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

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

    ProcessPoolExecutor类是一个Executor子类,它使用一个进程池来异步执行调用 . ProcessPoolExecutor使用多处理模块,它允许它侧向执行全局解释器锁定,但也意味着只能执行和返回可选对象 .

相关问题