首页 文章

多处理与线程Python

提问于
浏览
609

我试图了解multiprocessing优于threading的优点 . 我知道 multiprocessing 绕过Global Interpreter Lock,但是还有什么其他优点,并且 threading 不能做同样的事情吗?

8 回答

  • 688

    以下是我想出的一些优点/缺点 .

    多处理

    优点

    • 单独的内存空间

    • 代码通常很简单

    • 利用多个CPU和核心

    • 避免cPython的GIL限制

    • 消除了对同步原语的大多数需求,除非你使用共享内存(相反,它更像是IPC的通信模型)

    • 子进程是可中断/可杀死的

    • Python multiprocessing 模块包含有用的抽象,界面很像 threading.Thread

    • 必须使用cPython进行CPU绑定处理

    缺点

    • IPC更复杂,开销更大(通信模型与共享内存/对象)

    • 更大的内存占用

    线程

    优点

    • 轻量级 - 内存占用少

    • 共享内存 - 更容易从另一个上下文访问状态

    • 允许您轻松制作响应式用户界面

    • 正确释放GIL的cPython C扩展模块将并行运行

    • I / O绑定应用程序的绝佳选择

    缺点

    • cPython - 受GIL限制

    • 不可中断/可杀

    • 如果不遵循命令队列/消息泵模型(使用 Queue 模块),则手动使用同步原语成为必需(锁定粒度需要决策)

    • 代码通常难以理解并且正确 - 竞争条件的可能性会急剧增加

  • 25

    其他答案更多地关注多线程与多处理方面,但在python中必须考虑全局解释器锁(GIL) . 当创建更多数量(比如k)的线程时,通常它们不会将性能提高k倍,因为它仍将作为单线程应用程序运行 . GIL是一个全局锁,可以锁定所有内容,并且只允许单个线程执行,只使用一个内核 . 在使用Numpy,Network,I / O等C扩展的地方,性能确实会增加,在那里完成了大量后台工作并发布了GIL .
    因此,当使用线程时,只有一个操作系统级线程,而python创建伪线程,这些线程完全由线程本身管理,但基本上作为单个进程运行 . 抢占发生在这些伪线程之间 . 如果CPU以最大容量运行,您可能希望切换到多处理 .
    现在,在自包含执行实例的情况下,您可以选择池 . 但是,如果数据重叠,您可能希望进程通信,则应使用 multiprocessing.Process .

  • 171

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

    产卵过程比产生线程慢一点 . 一旦它们运行,就没有太大区别 .

  • 536

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

    请注意,由于GIL,应用程序实际上并不是同时执行两项操作,但我们所做的是将数据库上的资源锁定放入单独的线程中,以便可以在它与用户交互之间切换CPU时间 . CPU时间在线程之间得到限制 .

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

  • 5

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

  • 2

    进程可能有多个线程 . 这些线程可以共享内存,并且是进程内的执行单元 .

    进程在CPU上运行,因此线程驻留在每个进程下 . 流程是独立运行的单个实体 . 如果要在每个进程之间共享数据或状态,可以使用内存存储工具,如 Cache(redis, memcache)FilesDatabase .

  • 15

    还没有提到的另一件事是它取决于您在速度方面使用的操作系统 . 在Windows中,流程成本很高,因此在Windows中线程会更好,但在unix进程中比在windows变体中更快,因此在unix中使用进程更加安全,而且可以快速生成 .

  • 37

    正如问题所述,Python中的 Multiprocessing 是实现真正并行性的唯一真正方法 . Multithreading 无法实现此目的,因为GIL会阻止线程并行运行 .

    因此,线程在Python中可能并不总是有用,事实上,甚至可能会导致性能下降,具体取决于您要实现的目标 . 例如,如果您正在执行CPU绑定任务,例如解压缩gzip文件或3D渲染(任何CPU密集型),那么线程实际上可能会阻碍您的性能而不是帮助 . 在这种情况下,您可能希望使用 Multiprocessing ,因为此方法实际上并行运行并有助于分配手头任务的权重 . 可能会有一些开销,因为 Multiprocessing 涉及将脚本的内存复制到每个子进程中,这可能会导致更大的应用程序出现问题 .

    但是,当您的任务受IO限制时, Multithreading 会变得有用 . 例如,如果您的大多数任务都涉及等待API调用,那么您将使用 Multithreading ,因为在您等待时为什么不在另一个线程中启动另一个请求,而不是让您的CPU闲置 .

    TL;DR

    • Multithreading 是并发的,用于IO绑定任务

    • Multiprocessing 实现了真正的并行性,并用于CPU绑定任务

相关问题