我试图在python3中更熟悉asyncio的用法,但是我看不到何时应该使用async / await或线程。有区别吗?还是一个比另一个更容易使用。
例如,在这两个功能之间,一个功能优于另一个功能吗?
只需通用代码
def func1()
def func2()
threads = [threading.Thread(target=func1), threading.Thread(target=func2)]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
与
async def func1()
async def func2()
await asyncio.gather(func1(), func2())
答案 0 :(得分:0)
使用asyncio,一段代码可以使用await收回控制权。对于线程,这由Python调度程序处理。多线程采用了一种锁定机制来防止共享内存出现问题。多线程的另一个优点是它可以使用多个内核。
如果您想了解更多信息,这是一篇很棒的文章: https://medium.com/@nhumrich/asynchronous-python-45df84b82434
答案 1 :(得分:0)
我的建议是在所有情况下都使用线程,除非您正在编写高性能的并发应用程序,并且基准测试表明单独的线程太慢。
原则上,协程有很多优点。因为每个非阻塞操作序列都可以被视为原子操作(至少如果您不将它们与线程结合使用),所以它们更容易推理。而且由于价格便宜,您可以随意将它们旋转起来,以更好地分离问题,而不必担心会降低性能。
但是,协程在Python中的实际实现是一团糟。最大的问题是,每个可能阻塞的函数,可能会调用任何可能阻塞的代码,或者可能会调用任何可能...,可能会调用任何可能阻塞的代码的函数都必须用async
重写和await
关键字。这意味着,如果您要使用阻塞的库,或者要回调代码,并且要阻塞回调,那么根本就无法使用该库。由于这个原因,现在在CPython发行版中有一堆库的副本,甚至是内置语法的副本(async for
等),但是您不能指望大多数模块可以通过点数有两个版本。
线程没有这个问题。如果一个库不是为了线程安全而设计的,您仍然可以在多线程程序中使用它,方法是将其使用范围限制在一个线程内,或者通过使用锁保护所有使用。
因此,尽管存在问题,但在Python中使用线程总体上要容易得多。
有一些第三方协程解决方案可以避免“异步感染”问题,例如greenlet,但是除非将它们专门设计为可用于内部阻塞的库,否则您仍然无法使用它们使用协程。