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

2024-09-24 22:32:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我发现在Python3.4中,很少有用于多处理/线程的不同库:multiprocessingvsthreadingvsasyncio

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


Tags: 程序图书馆计算机事情线程multiprocessingvsthreadingvsasyncio
3条回答

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

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

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

TL;博士

做出正确的选择:

We have walked through the most popular forms of concurrency. But the question remains - when should choose which one? It really depends on the use cases. From my experience (and reading), I tend to follow this pseudo code:

if io_bound:
    if io_very_slow:
        print("Use Asyncio")
    else:
        print("Use Threads")
else:
    print("Multi Processing")
  • CPU Bound => Multi Processing
  • I/O Bound, Fast I/O, Limited Number of Connections => Multi Threading
  • I/O Bound, Slow I/O, Many connections => Asyncio

Reference


[注意]:

  • 如果您有一个长调用方法(即包含睡眠时间或惰性i/O的方法),那么最好的选择是asyncioTwistedTornado方法(协程方法),该方法使用单个线程作为并发
  • asyncio适用于Python3.4及更高版本
  • TornadoTwisted已准备就绪,因为Python2.7
  • uvloop是超快的asyncio事件循环(uvloop使asyncio快2-4倍)

[更新(2019)]:

  • JaprantoGitHub是一个基于uvloop的非常快速的流水线HTTP服务器

它们用于(稍微)不同的目的和/或要求。CPython(一个典型的主线Python实现)仍然有global interpreter lock,因此多线程应用程序(现在实现并行处理的标准方式)是次优的。这就是为什么multiprocessing可能比^{更受欢迎。但并不是每个问题都可以有效地分割成[几乎独立的]部分,因此可能需要大量的进程间通信。这就是为什么multiprocessing通常不比threading更受欢迎的原因

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

相关问题 更多 >