Python 2.7 concurrent.futures.ThreadPoolExecutor 不并行化

标签 python linux ubuntu parallel-processing

我在基于 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%。在利用率图中,4 个虚拟核心中只有一个被 100% 使用。使用的核心每 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 multiprocessing pickling error

最佳答案

听起来您看到的是 Python 的 Global Interpreter Lock 的结果(又名 GIL)。

In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once.

由于您的所有线程都在运行纯 Python 代码,因此实际上只有一个线程可以并行运行。这应该会导致只有一个 CPU 处于事件状态并且符合您对问题的描述。

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

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.

关于Python 2.7 concurrent.futures.ThreadPoolExecutor 不并行化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30378971/

相关文章:

python - 如何在plotly 3D曲面图中标记区域?

python - 使用 np.log(array) 时忽略负值

Python if 语句延迟

python - 可以在控制台中使用 Kafka 消息但不能使用 Python 库吗?

python - 如何在 'oh-my-zsh' 中显示 Python 版本

python - 将 JSON 变量输入到 python -mjson.tool

regex - 如何在 shell 脚本中使用正则表达式从 URL 中提取字符串字段值?

linux - 编译内核不使用 initrd

ubuntu - Ansible 剧本错误!在/home/中找不到角色 'Juniper.junos'

linux - 我的 LAMP 服务器一直在运行——这不是浪费资源吗?