Python 多任务编程:并发、进程、线程与线程安全详解

学习目标

通过本文学习,你将掌握:

  • 理解并发与并行的区别以及实际应用场景
  • 掌握 Python 多进程编程方式
  • 掌握 Process 创建、管理以及进程池的使用
  • 理解进程间通信机制 Queue
  • 掌握 Python 多线程创建方式
  • 掌握线程池 ThreadPoolExecutor 的使用
  • 理解线程安全问题以及互斥锁解决方案

一、并发与并行

在现代计算机中,一个程序往往需要同时处理多个任务,例如:

  • 下载文件的同时更新进度条
  • 浏览网页时同时加载图片和文字
  • 游戏中同时处理人物移动、声音播放和网络通信

这些场景都涉及多任务处理

多任务处理主要有两个概念:

  • 并发(Concurrency)
  • 并行(Parallelism)

虽然二者看起来类似,但是本质区别在于:

是否真正同时执行。


1. 并发

1.1 什么是并发

并发指的是:

一个 CPU 在同一时间段内处理多个任务,通过快速切换任务,让用户感觉多个任务同时进行。

例如:

一个人:

  • 回复消息
  • 喝水

实际过程:

复制代码
回复一句消息
↓
喝一口水
↓
继续回复
↓
继续喝水

微观上:

复制代码
串行执行

宏观上:

复制代码
同时完成多个任务

1.2 并发特点

① 单 CPU 也可以实现

一个 CPU 核心通过任务切换实现多个任务处理。

② 存在任务切换

CPU 会在不同任务之间快速切换。

③ 适合 IO 密集型任务

例如:

  • 文件读写
  • 网络请求
  • 数据库访问

原因:

当一个任务等待 IO 时:

复制代码
CPU空闲
↓
切换执行其他任务

提高 CPU 利用率。


2. 并行

2.1 什么是并行

并行指:

多个 CPU 核心真正同时执行多个任务。

例如:

两个人:

复制代码
A:回复消息

B:喝水

两个任务同时发生。


2.2 并行特点

① 需要多个 CPU 核心

例如:

4核 CPU:

复制代码
CPU1 → 任务A

CPU2 → 任务B

CPU3 → 任务C

CPU4 → 任务D

② 没有任务切换

多个任务真正同时运行。

③ 适合 CPU 密集型任务

例如:

  • 大规模计算
  • 图像处理
  • 数据分析
  • AI训练

3. 并发与并行区别

对比 并发 并行
CPU数量 一个或多个 多个
执行方式 交替执行 同时执行
本质 宏观同时,微观串行 真正同时
目标 提高资源利用率 提升计算速度
场景 IO密集型 CPU密集型

二、多进程编程

1. 什么是进程

进程是:

操作系统进行资源分配的基本单位。

例如:

电脑运行:

  • 浏览器
  • 微信
  • Python程序

它们都是不同进程。


进程特点

① 每个进程拥有独立内存

例如:

复制代码
进程A

内存空间A


进程B

内存空间B

二者互不影响。

② 进程之间不能直接共享数据

需要通过:

  • Queue
  • Pipe
  • Manager

进行通信。

③ 稳定性高

一个进程崩溃:

不会影响其他进程。


2. 创建进程

Python通过:

python 复制代码
multiprocessing

模块实现多进程。


方法一:Process创建进程

基本格式:

python 复制代码
Process(
    target=函数,
    args=参数
)

示例:

python 复制代码
import multiprocessing


def task(name):
    print(name)


if __name__=="__main__":

    p=multiprocessing.Process(
        target=task,
        args=("hello",)
    )

    p.start()

其中:

  • target:指定执行任务
  • args:传递参数
  • start():启动进程

start() 与 run()区别

start()

作用:

真正创建新的进程。

执行:

复制代码
主进程

    |
    |
 子进程

run()

只是普通方法调用:

python 复制代码
p.run()

不会创建新进程。


方法二:继承 Process 类

适合复杂任务。

示例:

python 复制代码
import multiprocessing


class MyProcess(
    multiprocessing.Process
):

    def run(self):

        print("子进程运行")


if __name__=="__main__":

    p=MyProcess()

    p.start()

3. Process常用方法

方法 作用
start() 启动进程
join() 等待进程结束
terminate() 强制结束进程
kill() 杀死进程
is_alive() 判断是否运行

三、进程池 Pool

1. 为什么使用进程池

如果创建:

复制代码
100个任务

手动创建:

复制代码
100个Process

效率低。

进程池:

提前创建:

复制代码
几个进程

不断重复执行任务。


创建进程池

python 复制代码
pool=multiprocessing.Pool(
    processes=4
)

表示:

创建4个工作进程。


2. Pool常用方法

apply()

同步执行:

特点:

复制代码
提交任务
↓
等待完成
↓
继续执行

apply_async()

异步执行:

特点:

复制代码
提交任务
↓
继续执行其他代码
↓
之后获取结果

适合大量任务。


四、进程间通信 Queue

为什么需要通信?

因为:

复制代码
进程A内存

≠

进程B内存

不能直接访问。


multiprocessing.Queue

示例:

python 复制代码
queue.put(data)


data=queue.get()

作用:

实现:

复制代码
进程A

  ↓

 Queue

  ↓

进程B

Pool中使用Queue

普通:

python 复制代码
multiprocessing.Queue()

不能用于Pool。

需要:

python 复制代码
multiprocessing.Manager().Queue()

五、多线程编程

1. 什么是线程

线程是:

CPU调度和执行的基本单位。

特点:

  • 依赖进程存在
  • 一个进程可以拥有多个线程
  • 多线程共享进程资源

例如:

浏览器:

复制代码
浏览器进程

 ├─ 页面线程

 ├─ 下载线程

 └─ 网络线程

2. 创建线程

Python:

python 复制代码
threading.Thread

方法一:Thread创建

python 复制代码
import threading


def task():

    print("线程运行")


t=threading.Thread(
    target=task
)

t.start()

方法二:继承Thread

python 复制代码
class Worker(threading.Thread):

    def run(self):

        print("线程任务")


t=Worker()

t.start()

六、线程池 ThreadPoolExecutor

当线程数量很多:

例如:

复制代码
1000个线程

管理困难。

线程池:

提前创建线程。


创建:

python 复制代码
from concurrent.futures import ThreadPoolExecutor


pool=ThreadPoolExecutor(
    max_workers=5
)

提交任务:

python 复制代码
future=pool.submit(
    task
)

获取结果:

python 复制代码
future.result()

七、线程安全问题

1. 什么是线程安全

多个线程共享数据时:

可能出现:

复制代码
线程A读取数据

线程B修改数据

线程A再次读取

数据错误

这就是线程安全问题。


2. 示例

多个线程:

python 复制代码
g_num +=1

实际上包含:

复制代码
读取

计算

写入

多个线程同时执行:

可能出现覆盖。


八、互斥锁 Lock

解决线程安全:

使用:

python 复制代码
threading.Lock()

作用:

同一时间只允许一个线程修改数据。


使用方式

获取锁:

python 复制代码
lock.acquire()

释放锁:

python 复制代码
lock.release()

示例:

python 复制代码
import threading


g_num=0

lock=threading.Lock()


def add():

    global g_num

    for i in range(10):

        lock.acquire()

        g_num+=1

        lock.release()

执行过程:

复制代码
线程A获得锁

↓

修改数据

↓

释放锁

↓

线程B获得锁

保证数据正确。


九、进程与线程总结

对比 进程 线程
资源 独立资源 共享资源
开销
通信 复杂 简单
稳定性 较低
适合 CPU密集型 IO密集型
Python模块 multiprocessing threading

十、总结

Python多任务编程主要包含:

多进程

特点:

  • 独立内存
  • 利用多核心CPU
  • 适合计算任务

核心:

复制代码
Process

Pool

Queue

多线程

特点:

  • 共享内存
  • 创建速度快
  • 适合等待任务

核心:

复制代码
Thread

ThreadPoolExecutor

Lock

最终选择:

复制代码
CPU密集型
        ↓
     多进程


IO密集型
        ↓
     多线程

掌握并发、进程、线程以及线程安全,是 Python 后端开发、爬虫、自动化、大数据处理和人工智能开发的重要基础。

相关推荐
君顾11 小时前
折扣卡 CPS 小程序定制:从业务流程到系统架构的实践指南
java·开发语言·折扣卡
2601_956319881 小时前
看到“2026年量化学习”时,交易想法要先拆成条件和动作
人工智能·python
大模型码小白2 小时前
Harness Engineering 驾驭工程:从使用到项目实战
大数据·数据库·人工智能·python·spring
坚定学代码2 小时前
static在c++中的使用
开发语言·c++
程序员小远2 小时前
自动化测试用例编写实例详解
自动化测试·软件测试·python·selenium·测试工具·职场和发展·测试用例
2601_962295582 小时前
Python UI自动化测试用例脚本编写指南
python·测试用例·uiautomator2·ui自动化测试·脚本编写
云雀衔光3 小时前
Java Spring AI MCP:在 Spring 里把 AI 接上你的业务系统
java·开发语言·人工智能·后端·测试工具·spring
重生之小比特3 小时前
【Java SE】数据类型与变量
java·开发语言·python
Yeniden3 小时前
Java 后端从零到企业级:第1篇 Java 基础语法——变量、数据类型与运算符
java·开发语言·apache