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

4.0 KiB

Python 多重处理

原文:https://python . land/python-concurrency/python-multi processing

有了 Python 多重处理库,我们可以编写真正的并行软件。当我们使用 Python 线程时,我们没有利用多个 CPU 或 CPU 内核。然而,有了这个库,我们将。首先,我们需要导入模块multiprocessing而不是threading

目录

基于多重处理的示例

下面是我们在基线版本线程版本中使用的代码的多处理版本:

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. 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()方法,我们可以向池提交工作。这项工作以简单函数调用的形式进行:

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 多处理的文章感兴趣!