Python多进程开发之如何轻松突破GIL瓶颈

 更新时间:2025年06月23日 08:11:55   作者:烛阴  
这篇文章主要来和大家详细介绍一下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,多进程

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 多进程并行计算

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 子进程类实现(面向对象)

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池自动分配和收集结果,极大提升效率!

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 通信(推荐)

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

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 加锁同步。

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多进程开发之如何轻松突破GIL瓶颈的文章就介绍到这了,更多相关Python GIL内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python装饰器使用实例:验证参数合法性

    Python装饰器使用实例:验证参数合法性

    这篇文章主要介绍了Python装饰器使用实例:验证参数合法性,本文直接给出代码实例,代码中包含详细注释,需要的朋友可以参考下
    2015-06-06
  • python 追踪except信息方式

    python 追踪except信息方式

    这篇文章主要介绍了python 追踪except信息方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-04-04
  • 教你用python实现一个无界面的小型图书管理系统

    教你用python实现一个无界面的小型图书管理系统

    今天带大家学习怎么用python实现一个无界面的小型图书管理系统,文中有非常详细的图文解说及代码示例,对正在学习python的小伙伴们有很好地帮助,需要的朋友可以参考下
    2021-05-05
  • wxPython色环电阻计算器

    wxPython色环电阻计算器

    这篇文章主要为大家详细介绍了wxPython色环电阻计算器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • Python爬虫自动化获取华图和粉笔网站的错题(推荐)

    Python爬虫自动化获取华图和粉笔网站的错题(推荐)

    这篇文章主要介绍了Python爬虫自动化获取华图和粉笔网站的错题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • python如何随机生成高强度密码

    python如何随机生成高强度密码

    这篇文章主要为大家详细介绍了python随机生成高强度密码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-08-08
  • python中闭包Closure函数作为返回值的方法示例

    python中闭包Closure函数作为返回值的方法示例

    闭包(closure)是函数式编程的重要的语法结构,Python也支持这一特性,下面这篇文章主要给大家介绍了关于python中闭包Closure函数作为返回值的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
    2017-12-12
  • Python编程之string相关操作实例详解

    Python编程之string相关操作实例详解

    这篇文章主要介绍了Python编程之string相关操作,结合实例形式分析了Python字符串相关函数与常见操作技巧,需要的朋友可以参考下
    2017-07-07
  • Python中turtle.write方法使用说明

    Python中turtle.write方法使用说明

    turtle模块以面向对象和面向过程的方式提供turtle图形基元,由于它使用Tkinter作为基础图形,因此需要安装有Tk支持的Python版本,下面这篇文章主要给大家介绍了关于Python中turtle.write方法使用说明的相关资料,需要的朋友可以参考下
    2022-02-02
  • Python多线程:主线程等待所有子线程结束代码

    Python多线程:主线程等待所有子线程结束代码

    这篇文章主要介绍了Python多线程:主线程等待所有子线程结束代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-04-04

最新评论