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

相关推荐
Dabei12 小时前
Android 语音助手简单实现与语音助手“执行任务”交流
android·前端
dongczlu12 小时前
iOS 循环引用篇 菜鸟都能看懂
前端
梅孔立12 小时前
【实用教程】python 批量解析 EML 邮件文件 存成txt ,可以利用 AI 辅助快速生成年终总结
开发语言·python
Alsn8612 小时前
26.IDEA 专业版中创建简单的 Web 项目并打包部署到本地Tomcat 9
前端·tomcat·intellij-idea
霍理迪12 小时前
HTML行内块标签——img、表单、音视频标签
前端·html
小小前端_我自坚强12 小时前
边缘函数 (Edge Functions)详解
前端
幼儿园技术家12 小时前
Hydration Mismatch 原理详解:SSR 项目中最容易踩的坑
前端
BoBoZz1912 小时前
ExtractSelectionUsingCells选择和提取三维模型中的特定单元(Cell)
python·vtk·图形渲染·图形处理
韩立学长12 小时前
【开题答辩实录分享】以《跳蚤市场二手物品交易推荐平台》为例进行选题答辩实录分享
python·django
June bug12 小时前
【Vue】EACCES: permission denied 错误
前端·javascript·vue.js