协慌网

登录 贡献 社区

多处理与线程 Python

我试图了解多处理线程处理的优势。我知道多处理程序可以绕过全局解释器锁,但是还有哪些其他优点,线程可以做同样的事情吗?

答案

这是我想到的一些优点 / 缺点。

多处理

优点

  • 单独的内存空间
  • 代码通常很简单
  • 利用多个 CPU 和内核
  • 避免了 cPython 的 GIL 限制
  • 消除了对同步原语的大多数需求,除非您使用共享内存(相反,它更多是 IPC 的通信模型)
  • 子进程是可中断 / 可杀死的
  • Python multiprocessing模块包含有用的抽象,其接口非常类似于threading.Thread
  • 必须使用 cPython 进行 CPU 绑定处理

缺点

  • IPC 稍微复杂一点,开销更多(通信模型与共享内存 / 对象的比较)
  • 更大的内存占用

穿线

优点

  • 轻巧 - 内存占用少
  • 共享内存 - 使从其他上下文访问状态更加容易
  • 使您可以轻松制作响应式用户界面
  • 正确释放 GIL 的 cPython C 扩展模块将并行运行
  • I / O 绑定应用程序的绝佳选择

缺点

  • cPython - 受 GIL 约束
  • 不间断 / 可杀死
  • 如果不遵循命令队列 / 消息泵模型(使用 “ Queue模块),则必须手动使用同步原语(需要确定锁定的粒度)
  • 代码通常更难于理解和正确处理 - 潜在的竞争条件急剧增加

threading模块使用线程, multiprocessing模块使用进程。区别在于线程在相同的内存空间中运行,而进程具有单独的内存。这使得在具有多处理的进程之间共享对象更加困难。由于线程使用相同的内存,因此必须采取预防措施,否则两个线程将同时写入同一内存。这就是全局解释器锁的作用。

生成过程比生成线程要慢一些。

线程的工作是使应用程序能够响应。假设您具有数据库连接,并且需要响应用户输入。如果没有线程,则如果数据库连接繁忙,则应用程序将无法响应用户。通过将数据库连接拆分为单独的线程,可以使应用程序响应速度更快。另外,由于两个线程处于同一进程中,因此它们可以访问相同的数据结构 - 良好的性能以及灵活的软件设计。

请注意,由于使用了 GIL,该应用实际上并未同时执行两项操作,但是我们所做的是将数据库上的资源锁放在单独的线程中,以便可以在它与用户交互之间切换 CPU 时间。 CPU 时间在线程之间分配。

多次处理是在您确实确实希望在任何给定时间完成一件以上的事情的时候。假设您的应用程序需要连接到 6 个数据库,并对每个数据集执行复杂的矩阵转换。将每个作业放在单独的线程中可能会有所帮助,因为当一个连接空闲时,另一个连接可能会花费一些 CPU 时间,但是由于 GIL 意味着您只使用一个 CPU 的资源,因此处理不会并行进行。 。通过将每个作业置于多处理流程中,每个作业都可以在其自己的 CPU 上运行并以最高效率运行。