python多进程和多线程问题

之前大家经常说python的多线程是假的,这里我们详细分析python的多进程和多线程问题,并进行个总结:

  1. 多进程(Multiprocessing):是"真"的。 是货真价实的操作系统级别的多进程,可以利用多核 CPU 并行计算。
  2. 多线程(Multithreading):也是"真"的,但有"锁"。 它们确实是操作系统的原生线程,不是 模拟出来的"虚拟线程"。但是,由于 Python GIL(全局解释器锁) 的存在,同一时刻只能有一个线程在 CPU 上执行 Python 字节码。

为了彻底明白,我们需要把"虚拟"、"并发"和"并行"这几个概念拆解开来。


1. 多进程 (multiprocessing):真正的人多力量大

当你使用 multiprocessing 库时,Python 会向操作系统申请创建全新的进程。

  • 它的本质:就像你手动打开了 4 个"命令提示符"窗口,分别运行了 4 个 Python 脚本。
  • 资源 :每个进程都有自己独立的 Python 解释器、独立的内存空间、独立的 GIL。
  • 结果 :因为大家都有自己的"地盘"和"解释器",所以它们可以同时在 CPU 的不同核心上跑。
  • 结论 :这是真正的物理并行。如果你有 8 核 CPU,起 8 个进程,CPU 占用率可以直接飙到 100%。

2. 多线程 (threading):真的线程,被"锁"住的手脚

这里是你疑惑的重点。很多人说 Python 线程是"假的",其实这种说法是不准确的。

  • 它的本质 :Python 的 threading 模块调用的是操作系统底层的原生线程接口(比如 Linux 的 pthreads 或 Windows 的线程)。所以从操作系统调度层面看,它们是真线程。

  • 为什么像"虚拟"的?(GIL 的锅)

    CPython(我们常用的 Python 版本)在执行代码时,必须持有一把锁,叫 GIL (Global Interpreter Lock)。

    • 规则 :任何时候,无论你开了多少个线程,同一个进程内,只能有一个线程持有 GIL 并在 CPU 上运行 Python 代码。

    • 工作方式 :

      1. 线程 A 拿到锁,跑一会儿。
      2. 线程 A 释放锁(或者被迫暂停)。
      3. 线程 B 抢到锁,跑一会儿。
      4. 线程 B 释放锁。
      • 这一切发生得非常快,看起来像是大家在同时动,但微观上是轮流动的。
  • 结论 :这是并发(Concurrency) ,而不是并行(Parallelism)。对于纯计算任务(比如做数学运算),多线程不仅不会变快,反而因为频繁切换上下文变慢。

3. 既然多线程会被锁住,为什么还要用?

虽然多线程在"算术"上没用,但在等待上非常有用。

场景:I/O 密集型任务(爬虫、读写文件、网络请求)

想象你在做网络爬虫:

  • 单线程 :发送请求 -> 傻等 1 秒服务器响应 -> 处理数据 -> 发送下一个。
  • 多线程 :
    • 线程 A 发请求 -> 遇到等待(I/O 阻塞) -> 自动释放 GIL 锁。
    • 线程 B 拿到锁 -> 发请求 -> 遇到等待 -> 释放锁。
    • 线程 C ...

在等待网络数据或磁盘读写时,Python 会释放 GIL。 这时候多线程就体现出优势了:虽然 CPU 还是只能处理一个人的活,但它可以在大家"排队等待"的时候去帮别人干活。

4. 所谓的"虚拟线程"是什么?

既然 Python 的 threading 是系统原生的,那有没有"虚拟"的?

有,那就是 协程(Coroutine) ,比如 Python 的 asyncio 库。

  • 协程:完全由程序(用户态)控制,不需要操作系统参与调度。它是在一个线程里,通过代码逻辑来切换任务。这才是真正意义上的"轻量级/虚拟"并发。

总结:形象的比喻

假设你的 CPU 是一个只有 4 个炉灶的厨房。

  1. 多进程(Multiprocessing):

    • 你雇佣了 4 个厨师,每人分到一个炉灶。
    • 效果:4 个人同时炒菜,速度 x4。
    • 代价:你要付 4 份工资,而且他们之间传递调料(数据)很麻烦,因为隔得远。
    • 适用:切肉、剁排骨(CPU 密集型计算)。
  2. 多线程(Threading):

    • 你只雇佣了 1 个厨师,但他要在 4 口锅之间来回跑。
    • 由于 GIL 的存在:这个厨师同一秒钟只能握住一把锅铲。
    • 如果任务是切菜(CPU 计算):他在 4 个案板间跑来跑去切,反而把时间浪费在跑路上了,不如老老实实切完一个再切下一个。
    • 如果任务是炖汤(I/O 等待):锅盖盖上炖汤的时候(等待网络响应),他可以去另一口锅炒菜。这样效率就高了。
    • 适用:炖汤、煮粥(爬虫、文件下载)。
  3. 协程(Asyncio):

    • 还是 1 个厨师,但他经过了精密的时间管理大师训练,知道在那一滴油刚热的时候迅速换手,没有任何多余的动作。

所以,Python 的多线程不是假的,只是被"限速"了。

相关推荐
海绵宝宝转agent6 分钟前
learn-claude-code第1-5章开源学习笔记分享
人工智能·笔记·python·学习
小奇不哭13 分钟前
ROS2 单节点,RGB-D 深度相机局部路径提取 + B 样条平滑路径 + YOLOv8 障碍物检测 + 深度测距,用于移动机器人视觉局部循迹。
python·yolov8·ros2·cv2·路径探索循迹
小小龙学IT25 分钟前
Python scikit-learn 机器学习库深度解析
python·机器学习·scikit-learn
Wang's Blog39 分钟前
Java 项目实战: 外卖平台优化-Nginx配置文件结构与块层级
java·开发语言·nginx
2601_962071571 小时前
类变量和全局变量的查找路径有什么区别?
开发语言·python
卷无止境2 小时前
独立开发者的"富矿地带":哪些垂直领域值得你押注一辈子?
后端·python
\光辉岁月/2 小时前
5.java-数组
java·开发语言
Java后端的Ai之路2 小时前
Python进阶探索29_eval内置函数
开发语言·python·探索·eval·内置函数
计算机毕业编程指导师2 小时前
计算机毕设选题推荐:基于Hadoop与Spark的Steam游戏数据分析系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习 深度学习
大数据·hadoop·python·计算机·spark·毕业设计·steam游戏
计算机毕业编程指导师2 小时前
【计算机毕设选题推荐】基于Hadoop+Spark的白鹿抖音评论大数据分析与可视化系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习 深度学习
大数据·hadoop·python·计算机·spark·毕业设计·抖音评论