geekdoc-python-zh/docs/pythonland/53.md

99 lines
4.0 KiB
Markdown

# Python 多重处理
> 原文:[https://python . land/python-concurrency/python-multi processing](https://python.land/python-concurrency/python-multiprocessing)
有了 Python 多重处理库,我们可以编写真正的并行软件。当我们使用 [Python 线程](https://python.land/python-concurrency/python-threads)时,我们没有利用多个 CPU 或 CPU 内核。然而,有了这个库,我们将。首先,我们需要[导入](https://python.land/project-structure/python-modules)模块`multiprocessing`而不是`threading`。
目录
* [基于多重处理的示例](#Multiprocessing_based_example "Multiprocessing based example")
* [Python 多处理池](#Python_multiprocessing_pool "Python multiprocessing pool")
* [继续学习](#Keep_learning "Keep learning")
## 基于多重处理的示例
下面是我们在[基线版本](https://python.land/python-concurrency/setting-the-baseline)和[线程版本](https://python.land/python-concurrency/python-threads)中使用的代码的多处理版本:
```py
import time
import multiprocessing
# A CPU heavy calculation, just
# as an example. This can be
# anything you like
def heavy(n, myid):
for x in range(1, n):
for y in range(1, n):
x**y
print(myid, "is done")
def multiproc(n):
processes = []
for i in range(n):
p = multiprocessing.Process(target=heavy, args=(500,i,))
processes.append(p)
p.start()
for p in processes:
p.join()
if __name__ == "__main__":
start = time.time()
multiproc(80)
end = time.time()
print("Took: ", end - start)
```
这段代码运行时间大概 23 秒,是线程版的一半!
如您所见,这在代码方面与线程版本几乎相同。线程模块和多处理模块被有意设计成非常等效。但是这一次 80 次调用的 *heavy* 完成的速度大约快了一倍。
Thank you for reading my tutorials. I write these in my free time, and it requires a lot of time and effort. I use ads to keep writing these *free* articles, I hope you understand! **Support me by disabling your adblocker on my website** or, alternatively, **[buy me some coffee](https://www.buymeacoffee.com/pythonland)**. It's much appreciated and allows me to keep working on this site!
我的测试系统(一台小型台式电脑)只有两个 CPU 内核,所以这解释了为什么它是两倍。如果我在我全新的笔记本电脑上运行这段代码,有 4 个更快的 CPU 内核,速度会快 4 倍以上。这完美地展示了在 CPU 受限代码的情况下,多处理为我们提供的线性速度提升。
## Python 多处理池
我们可以通过使用`multiprocessing.Pool(p)`让多处理版本更优雅、更快。这个 Python 多重处理助手创建了一个大小为`p`的进程池。如果您不为`p`提供一个值,它将默认为您系统中 CPU 内核的数量,这在大多数时候实际上是一个明智的选择。
通过使用`Pool.map()`方法,我们可以向池提交工作。这项工作以简单函数调用的形式进行:
```py
import time
import multiprocessing
# A CPU heavy calculation, just
# as an example. This can be
# anything you like
def heavy(n, myid):
for x in range(1, n):
for y in range(1, n):
x**y
print(myid, "is done")
def doit(n):
heavy(500, n)
def pooled(n):
# By default, our pool will have
# numproc slots
with multiprocessing.Pool() as pool:
pool.map(doit, range(n))
if __name__ == "__main__":
start = time.time()
pooled(80)
end = time.time()
print("Took: ", end - start)
```
这个版本的运行时与非池化版本大致相同,但是它必须创建更少的进程,因此效率更高。毕竟,我们没有创建 80 个流程,而是创建了 4 个,并且每次都重用它们。
## 继续学习
如果您想了解更多关于 Python 多处理和使用多处理池的知识,您可以前往官方文档。如果您经常使用命令行,您可能也会对我关于 [Bash 多处理](https://python.land/the-unix-shell/bash-multiprocessing)的文章感兴趣!