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 技术干货!如果觉得有用,记得收藏本文!

相关推荐
27669582923 分钟前
tiktok 弹幕 逆向分析
java·python·tiktok·tiktok弹幕·tiktok弹幕逆向分析·a-bogus·x-gnarly
cylat8 分钟前
Day59 经典时序预测模型3
人工智能·python·深度学习·神经网络
嘉恩督12 分钟前
视频人脸处理——人脸面部动作提取
python·音视频
WJ.Polar14 分钟前
Python数据容器-集合set
开发语言·python
Hockor21 分钟前
用 Kimi K2 写前端是一种什么体验?还支持 Claude Code 接入?
前端
杨进军22 分钟前
React 实现 useMemo
前端·react.js·前端框架
海底火旺24 分钟前
浏览器渲染全过程解析
前端·javascript·浏览器
你听得到1125 分钟前
揭秘Flutter图片编辑器核心技术:从状态驱动架构到高保真图像处理
android·前端·flutter
驴肉板烧凤梨牛肉堡26 分钟前
浏览器是否支持webp图像的判断
前端
Xi-Xu27 分钟前
隆重介绍 Xget for Chrome:您的终极下载加速器
前端·网络·chrome·经验分享·github