
概述
我们在Python异步编程实战入门:从概念到实战讨论了异步编程的相关方法,并指出异步编程适用于 IO 密集型应用的编写。在此文中,我们将使用multiprocessing
实践 Python 中的多进程编程。与异步编程不同,多进程编程可以解决计算密集型应用,而且可以绕过 Python 运行中最令人沮丧的组件——GIL
。
多进程编程可以充分利用现代处理器多核的特性,将代码分布到每个CPU核中运行。与异步编程类似,多进程编程的 API 等也在不断变化,笔者使用 Python 版本为3.11
,CPU为i7-10875H
,操作系统为Windows 10
。
与上一篇文章类似,本文不会大篇幅的介绍相关概念,而侧重于通过代码示例帮助读者快速掌握多进程编程。
基础模式
在真正讨论多进程编程的相关概念及编程方法前,我们首先给出一个简单的例子:
1 | from multiprocessing import Process |
该代码输出结果为:
1 | Main task |
此代码较为简单,但展示了多进程编程的基础模式。我们定义一个函数,并使用Process(target=task)
将其包装为一个进程,随后调用process.start()
启用此进程,最后使用process.join()
阻塞主进程等待task
进程完成。
注意,在多进程编程中,必须使用
if __name__ == '__main__':
来标识代码的开始
在上文中,我们提及使用process.join
阻塞主进程。对于部分读者而言,阻塞可能是一个新鲜概念。简单来说,阻塞意味着等待,即主进程等待task
子进程完成任务。如下图:
读者可以尝试去掉process.join()
,会观察到输出结果不变。这是因为Python
会隐式调用join
方法,但我们并不推荐读者依赖于此隐式调用,这可能导致一些意外情况的发生。
在此处,我们需要强调在多进程编程中最重要的概念就是阻塞。可以认为多进程编程的核心就是设计阻塞
在此处,我们再给出一个需要使用参数的进程的示例:
1 | from multiprocessing import Process |
我们可以通过args
输入函数所需要的参数。上述代码输出为:
1 | Main task |