已同步是什么意思啊 同步是什么( 三 )


上下文切换在所有运行的任务间公平地共享 CPU 所需的工作,称为上下文切换,能够影响应用程序的性能 。对同步应用程序来说,这项工作是由操作系统完成的,而且基本上是一个黑箱,不需要配置或微调选项 。对异步应用程序来说,上下文切换是由循环完成的 。
默认的循环实现由asyncio提供,是用 Python 编写的,效率不是很高 。而 uvloop 包提供了一个备选的循环方案,其中部分代码是用 C 编写的来实现更好的性能 。Gevent 和 Meinheld 所使用的事件循环也是用 C 编写的 。Eventlet 用的是 Python 编写的循环 。
高度优化的异步循环比操作系统在进行上下文切换方面更有效率,但根据我的经验,要想看到实际的效率提升,你运行的并发量必须非常大 。对于大部分应用程序,我不认为同步和异步上下文切换之间的性能差距有多明显 。
扩展性我认为异步更快这个神话的来源是,异步应用程序通常会更有效地使用 CPU、能更好地进行扩展并且扩展方式比同步更灵活 。
如果上面示意图中的同步服务器同时收到 100 个请求,想一下会发生什么 。这个服务器同时最多只能处理 4 个请求,因此大部分请求会停留在一个队列中等待,直到它们被分配一个 worker 。
与之形成对比的是,异步服务器会立即创建 100 个任务(或者使用混合模式的话,在 4 个异步 worker 上每个创建 25 个任务) 。使用异步服务器,所有请求都会立即开始处理而不用等待(尽管公平地说,这种方案也还会有其它瓶颈会减慢速度,例如对活跃的数据库连接的限制) 。
如果这 100 个任务主要使用 CPU,那么同步和异步方案会有相似的性能,因为每个 CPU 运行的速度是固定的,Python 执行代码的速度总是相同的,应用程序要完成的工作也是相同的 。但是,如果这些任务需要做很多 I/O 操作,那么同步服务器只能处理 4 个并发请求而不能实现 CPU 的高利用率 。而另一方面,异步服务器会更好地保持 CPU 繁忙,因为它是并行地运行所有这 100 个请求 。
你可能会想,为什么你不能运行 100 个同步 worker,那样,这两个服务器就会有相同的并发能力 。要注意,每个 worker 需要自己的 Python 解释器以及与之相关联的所有资源,再加上一份单独的应用程序拷贝及其资源 。你的服务器和应用程序的大小将决定你可以运行多少个 worker 实例,但通常这个数字不会很大 。另一方面,异步任务非常轻量,都运行在单个 worker 进程的上下文中,因此具有明显优势 。
综上所述,只有如下场景时,我们可以说异步可能比同步快:

  • 存在高负载(没有高负载,访问的高并发性就没有优势)
  • 任务是 I/O 绑定的(如果任务是 CPU 绑定的,那么超过 CPU 数目的并发并没有帮助)
  • 你查看单位时间内的平均请求处理数 。如果你查看百思特网单个请求的处理时间,你不会看到有很大差别,甚至异步可能更慢,因为异步有更多并发的任务在争夺 CPU 。
结论希望本文能解答异步代码的一些困惑和误解 。我希望你能记住以下两个关键点:
  • 异步应用程序只有在高负载下才会比同步应用程序做得更好
  • 多亏了 greenlets,即使你用一般方式写代码并使用 Flask 或 Django 之类的传统框架,也能从异步中受益 。
如果你想要了解更多关于异步系统如何工作的细节,可以百思特网查看 YouTube 上我在 PyCon 的演讲 Asynchronous Python for the Complete Beginner。
作者介绍:
Miguel Grinberg 是一名软件工程师、摄影师和电影制作人,住在爱尔兰的德罗赫拉 。你可以在 Facebook 、 Google 、 LinkedIn 、 Github 和 Twitter 他 。


以上关于本文的内容,仅作参考!温馨提示:如遇健康、疾病相关的问题,请您及时就医或请专业人士给予相关指导!

「四川龙网」www.sichuanlong.com小编还为您精选了以下内容,希望对您有所帮助: