摘要:本文介绍了Python中的并发编程概念及其发展历程。首先解释了并发的定义及其在编程中的重要性,然后分别阐述了线程/多线程和进程/多进程的概念与区别。文章着重分析了Python在并发编程方面的优势,包括语法糖特性、社区支持和丰富的并发API,同时也指出了Python受限于全局解释器锁(GIL)的局限性,这使得Python无法实现真正的多线程并行。最后简要说明了GIL的工作原理及其对Python线程执行的影响。
目录
[Python 中的并发 ------ 简介](#Python 中的并发 —— 简介)
[丰富的并发编程专用 API](#丰富的并发编程专用 API)
[Python 实现并发应用的局限性](#Python 实现并发应用的局限性)
Python 中的并发 ------ 简介
什么是并发?
简单来说,并发是指两个或多个事件在同一时间发生。并发是一种自然现象,因为在任意时刻,都有诸多事件同时发生。
在编程领域,并发指的是两个任务的执行过程出现重叠。通过并发编程,应用程序和软件系统的性能能够得到提升,因为我们可以同时处理多个请求,而非等待前一个请求执行完毕后再进行后续操作。
并发的发展历程
以下几点将为大家简要介绍并发的发展历程:
源于铁路系统的设计理念
并发的概念与铁路系统密切相关。铁路系统的运行需要实现多列列车在同一轨道网络中行驶,且每列列车都能安全抵达目的地,这一需求催生了对并发管理的思考。
学术界的并发计算研究
计算机科学领域对并发的研究热潮,始于埃德加・W・迪杰斯特拉在 1965 年发表的一篇研究论文。在这篇论文中,他发现并解决了并发控制的核心问题 ------ 互斥问题。
高级并发原语的出现
近年来,高级并发原语的引入,让开发者能够实现更完善的并发解决方案。
编程语言推动并发技术发展
谷歌的 Go 语言、Rust 语言以及 Python 等编程语言,在并发相关领域取得了重大发展,为我们实现更优质的并发方案提供了支持。
什么是线程与多线程?
线程是操作系统中可执行的最小单位,它本身并非独立程序,而是运行在程序内部的执行单元。也就是说,线程之间并非相互独立,每个线程会与其他线程共享代码段、数据段等资源,线程也被称为 "轻量级进程"。
一个线程由以下组件构成:
- 程序计数器:存储下一条待执行指令的地址
- 栈区
- 一组寄存器
- 唯一标识 ID
而多线程,指的是中央处理器(CPU)通过同时执行多个线程,实现对操作系统资源的管理能力。多线程的核心思想是将一个进程拆分为多个线程,以此实现并行处理。我们可以通过一个例子理解多线程的概念:
示例
假设我们运行一个进程,需要打开 Microsoft Word 并在其中输入内容。系统会为 "打开 Word 软件" 分配一个线程,为 "在软件中输入内容" 分配另一个线程;如果后续需要编辑已有内容,系统还会再分配一个线程专门处理编辑任务,以此类推。
什么是进程与多进程?
进程是操作系统中代表待执行基本工作单元的实体。简单来说,我们在文本文件中编写计算机程序,当运行该程序时,它就成为一个进程,执行程序中定义的所有任务。进程的生命周期会经历启动、就绪、运行、等待和终止等不同阶段。

一个进程可以只有一个线程(称为主线程),也可以包含多个线程,每个线程都拥有独立的寄存器组、程序计数器和栈区。

而多进程,指的是在一台计算机系统中使用两个或多个 CPU 单元。我们的核心目标是充分挖掘硬件的性能潜力,要实现这一点,就需要利用计算机系统中所有可用的 CPU 核心,多进程正是实现该目标的最佳方式。

Python 是最受欢迎的编程语言之一,以下是使其适用于开发并发应用的几大原因:
语法糖特性
语法糖是编程语言中为了提升代码可读性、简化表达而设计的语法形式,它让语言更贴合人类的使用习惯,能让代码的表达更清晰、更简洁,也能根据个人偏好选择不同的书写风格。Python 提供了魔术方法,开发者可以定义魔术方法作用于对象,这些魔术方法作为语法糖,可与更易理解的关键字绑定使用。
庞大的社区支持
在人工智能、机器学习、深度学习和量化分析等领域,数据科学家和数学家广泛使用 Python,使得 Python 的普及度大幅提升。
丰富的并发编程专用 API
Python 2 和 Python 3 拥有大量专用于并行 / 并发编程的应用程序编程接口(API),其中最常用的包括threading 、concurrent.futures 、multiprocessing 、asyncio 、gevent 和greenlets等。
Python 实现并发应用的局限性
Python 在开发并发应用时存在一项局限性,即 Python 中存在的全局解释器锁(GIL)。全局解释器锁导致 Python 无法利用 CPU 的多个核心,因此我们可以认为 Python 中并不存在真正的线程。关于全局解释器锁的概念,可通过以下内容理解:
全局解释器锁(GIL)
这是 Python 领域最具争议的话题之一。在 CPython 解释器中,全局解释器锁是一种互斥锁,用于保证线程安全。也就是说,全局解释器锁会阻止多个线程并行执行 Python 代码,同一时间只有一个线程能持有该锁,线程想要执行,就必须先获取这把锁。
不过,Python 中的部分库和实现版本不受全局解释器锁的影响,例如Numpy 、JPython 和IronPython,这些库的运行无需与全局解释器锁产生交互。