Python多进程开发实战:轻松突破GIL瓶颈

1. 为啥要用多进程?先认清GIL

Python多线程为何没法加速CPU密集型任务?因为GIL(全局解释器锁):在主流的CPython解释器中,无论多少线程归根结底同时只有一个线程在执行Python字节码,严重影响CPU计算性能的并行。

多进程机制完美绕开了GIL:每个进程拥有自己的Python解释器和内存空间,真正多核、多CPU并行执行,CPU密集型任务大大提速!


2. Python多进程基础用法:multiprocessing库

Python 内置标准库 multiprocessing,API与threading非常类似,上手容易。

2.1 Proces介绍:

Process([group [, target [, name [, args [, kwargs]]]]])

  • target 表示调用对象
  • args 表示调用对象的位置参数元组
  • kwargs 表示调用对象的字典
  • name 为别名
  • group 实质上不使用

2.2 Hello,多进程

python 复制代码
from multiprocessing import Process
import os

def worker():
    print('子进程PID:', os.getpid())

if __name__ == '__main__':
    p = Process(target=worker)
    p.start()
    p.join()
    print('主进程结束')

注意! Windows下多进程要写在 if __name__ == '__main__': 保护块内,否则会无限递归启动进程。


2.3 多进程并行计算

python 复制代码
from multiprocessing import Process
import time

def task(name):
    print(f'{name} 开始')
    time.sleep(2)
    print(f'{name} 结束')

if __name__ == '__main__':
    proc_list = []
    for i in range(3):
        p = Process(target=task, args=(f'进程{i+1}',))
        p.start()
        proc_list.append(p)
    for p in proc_list:
        p.join()
    print('所有子进程结束')

多个进程可并发分担任务,真正多核利用!

2.4 子进程类实现(面向对象)

python 复制代码
import multiprocessing
import time

class ClockProcess(multiprocessing.Process):
    def __init__(self, interval):
        multiprocessing.Process.__init__(self)
        self.interval = interval

    def run(self):
        n = 5
        while n > 0:
            print("当前时间: {0}".format(time.ctime()))
            time.sleep(self.interval)
            n -= 1


if __name__ == '__main__':
    p = ClockProcess(3)
    p.start()

3. 进阶:进程池批量并行(Process Pool)

大量任务并发时,手动管理进程很麻烦,用Pool池自动分配和收集结果,极大提升效率!

python 复制代码
from multiprocessing import Pool
import os, time

def square(n):
    print('计算', n, '在进程', os.getpid())
    time.sleep(1)
    return n * n

if __name__ == '__main__':
    with Pool(processes=3) as pool:
        results = pool.map(square, range(5))
    print('返回结果:', results)

比循环创建 Process 简洁得多,还能自动分配CPU,每个子进程并发执行给定任务。


4. 多进程间数据:通信与共享

  • 每个进程独立内存,不能像多线程那样直接共享变量
  • 多进程用队列(Queue)、管道(Pipe)或特殊共享对象实现

4.1 用队列 Queue 通信(推荐)

python 复制代码
from multiprocessing import Process, Queue

def producer(q):
    for i in range(5):
        q.put(i)
    q.put(None)  # 发送结束标记

def consumer(q):
    while True:
        item = q.get()
        if item is None:
            break
        print('消费:', item)

if __name__ == '__main__':
    q = Queue()
    p1 = Process(target=producer, args=(q,))
    p2 = Process(target=consumer, args=(q,))
    p1.start()
    p2.start()
    p1.join()
    p2.join()

4.2 共享内存变量:Value 与 Array

python 复制代码
from multiprocessing import Process, Value, Array

def worker(val, arr):
    val.value += 10
    for i in range(len(arr)):
        arr[i] *= 2

if __name__ == '__main__':
    num = Value('i', 5)                # int类型共享变量
    arr = Array('i', [1, 2, 3, 4])     # 数组
    p = Process(target=worker, args=(num, arr))
    p.start()
    p.join()
    print('num =', num.value)
    print('arr =', list(arr))

5. 多进程安全:锁机制

多进程也需防止竞争条件,通过 Lock/Manager 加锁同步。

python 复制代码
from multiprocessing import Process, Lock, Value

def add(lock, counter):
    for _ in range(100000):
        with lock:
            counter.value += 1

if __name__ == '__main__':
    lock = Lock()
    counter = Value('i', 0)
    procs = [Process(target=add, args=(lock, counter)) for _ in range(4)]
    for p in procs:
        p.start()
    for p in procs:
        p.join()
    print('结果:', counter.value)

6. 多进程vs多线程,该如何选?

  • CPU密集(数值计算/图像处理/大数据科学):用多进程"跑满CPU"突破GIL
  • IO密集(爬虫/网络/磁盘/数据库交互):多线程即可,更省内存和切换开销

点个赞,关注我获取更多实用 Python 技术干货!如果觉得有用,记得收藏本文!

相关推荐
子兮曰4 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰4 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
默_笙4 天前
🍙 给每个请求过安检:FastAPI 是怎么把校验写进类型注解的
python
前端小万4 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝4 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
qq_426003964 天前
启动playwright录制codegen生成自动化测试脚本
python·自动化
虎头金猫4 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
三十而立洋4 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
长沙三为智能科技4 天前
家政小程序开发从0到上线:五阶段交付流程与验收清单
python
伞伞悦读4 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python