多处理与线程化Python

我想了解多 线程的多处理优势。 我知道全局解释器锁可以解决多处理问题 ,但是还有什么其他的优点,而且可以通过线程来做同样的事情呢?

threading模块使用线程, multiprocessing模块使用进程。 不同之处在于线程在同一个内存空间中运行,而进程具有单独的内存。 这使得在多进程进程之间共享对象变得更加困难。 由于线程使用相同的内存,所以必须采取预防措施,或者两个线程同时写入相同的内存。 这是全球解释器锁的用途。

产卵过程比产卵线程慢一点。 一旦他们跑步,没有太大的区别。

这是我提出的一些优点/缺点。

优点

  • 分开的内存空间
  • 代码通常很简单
  • 利用多个CPU和内核
  • 避免cPython的GIL限制
  • 消除同步原语的大部分需求,除非使用共享内存(相反,它更像是IPC的通信模型)
  • subprocess是可中断的/可以进行的
  • Python multiprocessing模块包含有用的抽象接口,就像threading.Thread一样
  • 必须用cPython进行CPU绑定处理

缺点

  • IPC更复杂一些,开销更多(通信模式与共享内存/对象)
  • 更大的内存占用

穿线

优点

  • 轻量级 – 低内存占用
  • 共享内存 – 使访问状态从另一个上下文更容易
  • 允许您轻松制作响应式用户界面
  • 正确释放GIL的cPython C扩展模块将并行运行
  • I / O绑定应用程序的最佳select

缺点

  • cPython – 服从GIL
  • 不可中断/可打
  • 如果不遵循命令队列/消息泵模型(使用Queue模块),则手动使用同步原语成为必需(需要确定locking的粒度)
  • 代码通常很难理解和正确 – 竞争条件的潜力急剧增加

线程的工作是使应用程序响应。 假设你有一个数据库连接,你需要响应用户input。 如果没有线程,数据库连接繁忙,应用程序将无法响应用户。 通过将数据库连接拆分为一个单独的线程,可以使应用程序响应更快。 同样因为两个线程处于同一个进程中,他们可以访问相同的数据结构 – 性能良好,并且具有灵活的软件devise。

请注意,由于GIL,应用程序实际上并不是一次做两件事,但我们所做的是将数据库上的资源锁放入一个单独的线程,以便CPU时间可以在它和用户交互之间切换。 CPU时间在线程之间分配。

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

关键优势是隔离。 崩溃的过程不会导致其他进程,而崩溃的线程可能会对其他线程造成严重破坏。

另一件没有提到的事情是,它取决于你在哪个操作系统上使用速度。 在Windows中,进程代价高昂,所以线程在Windows中会更好,但是在unix进程中比在Windows上更快,所以在unix中使用进程会更加安全,加快产生。

其他答案更侧重于multithreading与多处理方面,但在Python全局解释器锁( GIL )必须考虑。 当创build更多的线程(比如说k个 )时,通常它们不会将性能提高k倍,因为它仍将作为单线程应用程序运行。 GIL是一个全局锁,它将所有东西都locking,只允许单个线程执行,只使用一个内核。 性能确实在使用像numpy,Network,I / O这样的C扩展的地方增加了,在这里完成了大量的后台工作,并释放了GIL。
所以当使用线程时,只有一个操作系统级别的线程,而python创build完全由线程本身pipe理的伪线程,但本质上是作为单个进程运行的。 先占权在这些伪线之间。 如果CPU以最大容量运行,则可能需要切换到多处理。
现在,如果是自包含执行的实例,则可以select使用池。 但是在数据重叠的情况下,您可能希望进程进行通信,您应该使用multiprocessing.Process

进程可能有多个线程可能共享内存。 如果你考虑多进程vsmultithreading,线程除了在这个过程中。 进程正在CPU上运行。 所以线程驻留在进程下面。 进程是独立运行的独立实体。 如果要在进程之间共享数据或状态,可以使用存储数据(例如Cache(redis,memcache),Files,Database)的常见位置,