Python:异步线程有什么优势?

les*_*nik 14 python multithreading asynchronous async-await python-asyncio

我很难理解如何以及为什么异步功能在python中工作,我仍然不确定我是否正确理解了所有内容(特别是'为什么'部分).如果我错了,请纠正我.

异步方法和线程的目的是使同时处理多个任务成为可能.

线程方法看起来简单直观.如果python程序同时处理多个任务,我们每个任务都有一个线程(可能有子线程),每个线程的堆栈反映了当前处理相应任务的阶段.一切都很简单,有一些易于使用的机制来启动新线程并等待它的结果.

据我所知,这种方法的唯一问题是线程很昂贵.

另一种方法是使用async协同程序.我可以通过这种方法看到一些不便之处.我只会说出几个人的名字.我们现在有两种方法:通常的方法和async方法.90%的时间唯一的区别是你需要记住这个方法是,async并且await在调用此方法时不要忘记使用关键字.是的,你不能async从正常方法中调用方法.所有这些async- await程序周围的语法垃圾只是表明这种方法能够控制消息循环.

线程方法没有所有这些不便之处.但是async- await方法允许处理比线程方法更多的并发任务.怎么可能?

对于每个并发任务,我们仍然有一个调用堆栈,现在它只是一个协程调用堆栈.我不太确定,但看起来这是关键的区别:通常的堆栈是操作系统堆栈,它们很昂贵,协程栈只是一个python结构,它们便宜得多.这是我的理解吗?

如果这是正确的,那么从操作系统线程/调用堆栈中解除python线程/调用堆栈以使python线程更便宜会不会更好?

对不起,如果这个问题很愚蠢.我确信有一些原因async- await选择了方法.只是想了解这些原因.

更新:

对于那些不认为这个问题不好而且过于宽泛的人.

这是一篇不屈不挠的文章- 首先解释为什么线程不好而广告async接近.主要论点:线程是邪恶的,很难推断可以同时从任意数量的线程执行的例程.

感谢Nathaniel J. Smith(python Trio图书馆的作者)建议这个链接.

顺便说一句,文章中的论点对我来说并不令人信服,但仍然有用.

Luk*_*ith 10

这篇文章回答了你的问题。

特尔;博士?

由于GIL(全局解释器锁),Python 中的线程效率低下,这意味着多个线程不能像在多处理器系统上期望的那样并行运行。此外,您必须依靠解释器在线程之间切换,这增加了低效率。

asyc/ asyncio允许在单个线程内并发。这使您作为开发人员可以对任务切换进行更细粒度的控制,并且可以为并发 I/O 绑定任务提供比 Python 线程更好的性能。

您没有提到的第三种方法是multiprocessing。这种方法使用进程进行并发,并允许程序充分利用具有多核的硬件。

  • GIL 是一个问题,但它并没有解释为什么 asyncio 方法比线程更好。它解释了为什么线程并不比 asyncio 好多少。是的,由于 GIL(稍微简化),在给定时刻只能运行一个 python 线程。情况与 asyncio 相同 - 在给定时刻只有一个任务正在运行。还有一个论点:线程调度器(或调度器或选择器)不够好,可以选择在 IO 操作中被阻塞的线程。我不确定这是否正确(请参阅 Dunes 对第二个答案的评论)。这篇文章没有回答我的问题:(。 (12认同)