当前位置: 首页 > 知识库问答 >
问题:

Python3中的多处理vs多线程vs异步IO

萧修永
2023-03-14

但我不知道该用哪一个或是“推荐的”。他们做的是相同的事情,还是不同?如果是,哪一个用于什么?我想写一个在我的计算机中使用多核的程序。但我不知道我应该去哪个图书馆。

共有3个答案

商麒
2023-03-14

在多处理中,您可以利用多个CPU来分配计算。由于每个CPU并行运行,因此您可以有效地同时运行多个任务。您可能希望对CPU限制的任务使用多处理。例如,试图计算一个庞大列表中所有元素的总和。如果您的机器有8个内核,您可以将列表“剪切”为8个较小的列表,并在单独的内核上分别计算每个列表的总和,然后将这些数字相加。这样做,您将获得~8倍的加速。

在(多)线程中,您不需要多个CPU。想象一下一个向web发送大量HTTP请求的程序。如果使用单线程程序,它会在每次请求时停止执行(阻塞),等待响应,然后在收到响应后继续。这里的问题是,在等待外部服务器执行任务时,您的CPU没有真正执行任务;同时,它本可以做一些有用的工作!解决方法是使用线程——您可以创建许多线程,每个线程负责从web请求一些内容。线程的好处在于,即使它们在一个CPU上运行,CPU也会不时地“冻结”一个线程的执行,并跳到另一个线程的执行(这称为上下文切换,它以不确定的间隔不断发生)。因此,如果您的任务是I/O绑定的,请使用线程。

asyncio本质上是线程,在这里不是CPU而是程序员(实际上是应用程序)决定上下文切换发生的时间和地点。在Python中,您使用await关键字来暂停协同程序的执行(使用async关键字定义)。

越学博
2023-03-14

它们用于(稍微)不同的目的和/或要求。CPython(一个典型的主线Python实现)仍然具有全局解释器锁,因此多线程应用程序(目前实现并行处理的标准方式)是次优的。这就是为什么多处理可能优于线程。但并不是每个问题都可以有效地分割成[几乎独立的]部分,因此可能需要大量的进程间通信。这就是为什么通常情况下,多处理可能不优于线程

asyncio(该技术不仅在Python中可用,其他语言和/或框架也有,例如Boost.ASIO)是一种有效处理来自多个同时源的大量I/O操作的方法,而不需要并行代码执行。因此,它只是针对特定任务的一个解决方案(确实是一个很好的解决方案!),而不是一般的并行处理。

田志
2023-03-14

我们已经介绍了最流行的并发形式。但是问题仍然存在——什么时候应该选择哪一个?这真的取决于用例。根据我的经验(和阅读),我倾向于遵循这个伪代码:

if io_bound:
    if io_very_slow:
        print("Use Asyncio")
    else:
        print("Use Threads")
else:
    print("Multi Processing")
  • CPU限制=

参考文献

[注]:

  • 如果您有一个长调用方法(即包含睡眠时间或惰性i/O的方法),那么最好的选择是asyncio、Twisted或Tornado方法(协同路由方法),该方法使用单个线程作为并发处理。

[更新(2019)]:

  • Japranto(GitHub)是一个基于uvloop的非常快速的流水线HTTP服务器
 类似资料:
  • 问题内容: 我试图理解多处理比线程的优势。我知道多处理绕过了全局解释器锁,但是还有什么其他优点,线程不能做同样的事情? 问题答案: 该模块使用线程,该模块使用进程。不同之处在于线程在相同的内存空间中运行,而进程具有单独的内存。这使得在具有多处理的进程之间共享对象更加困难。由于线程使用相同的内存,因此必须采取预防措施,否则两个线程将同时写入同一内​​存。这就是全局解释器锁的作用。 生成过程比生成线程

  • 问题内容: 我发现在Python 3.4中,用于多处理/线程的库很少:多处理vs线程与asyncio。 但是我不知道使用哪个,或者是“推荐的”。他们做的是同一件事还是不同?如果是这样,则将哪一个用于什么?我想编写一个在计算机上使用多核的程序。但是我不知道我应该学习哪个图书馆。 问题答案: 它们旨在(略有)不同的目的和/或要求。CPython(典型的主线Python实现)仍然具有全局解释器锁,因此多

  • 我知道这个问题已经被问过很多次了。但是有些事情我从来没有找到答案。所以希望有人能给我一些启发。 我们都知道,AsyncTask和Thread是执行后台任务以避免ANR问题的选项。建议asynctask只能用于短期运行的任务,而线程可以用于长期运行的任务。asynctask不应用于长任务的原因是众所周知的,这与asynctask可能导致的泄漏有关,因为它可能在活动销毁后继续运行。这很有说服力。然而,

  • 问题内容: 我正在使用Python的模块并行处理大型numpy数组。阵列在主进程中使用内存映射。之后,分叉该过程(我想)。 一切似乎都正常,除了我得到类似以下内容的行: 在单元测试日志中。尽管如此,测试仍然可以通过。 知道那里发生了什么吗? 使用Python 2.7.2,OS X,NumPy 1.6.1。 更新: 经过一些调试后,我将原因找出到使用此内存映射的numpy数组(的一小部分)作为调用输

  • 线程中使用 java.lang.Runnable 如果用户在代码中通过 java.lang.Runnable 新启动了线程或者采用了线程池去异步地处理一些业务,那么需要将 SOFATracer 日志上下文从父线程传递到子线程中去,SOFATracer 提供的 com.alipay.common.tracer.core.async.SofaTracerRunnable 默认完成了此操作,大家可以按照

  • 多线程类似于同时执行多个不同程序,多线程运行有如下优点: 使用线程可以把占据长时间的程序中的任务放到后台去处理。 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度 程序的运行速度可能加快 在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。 线程在执行过程中与进