同步了是什么意思啊,同步是怎么回事

同步了是什么意思啊,同步是怎么回事,第1张

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

你听过有人说异步Python代码比“普通(或同步)Python代码”快吗?真的是那样吗?

“同步”和“异步”是什么意思?

Web应用程序通常在短时间内处理来自不同客户端的许多请求。为了避免处理延迟,需要考虑并行处理多个请求,这通常称为“并发”。

在本文中,我将继续使用Web应用程序作为示例,但是请记住,还有其他类型的应用程序也可以从并发完成多个任务中受益,因此本文的讨论不仅仅针对Web应用程序。

术语“同步”和“异步”指的是编写并发应用程序的两种方式。所谓的“同步”服务器使用底层操作系统支持的线程和进程来实现这种并发性。以下是同步部署的示意图:

在本例中,我们有5个客户端,它们都向应用程序发送请求。此应用程序的访问门户是一个Web服务器,它通过将服务分配给一组服务器工作人员来充当负载平衡器,这些工作人员可以实现为进程、线程或两者的组合。这些工作者执行负载平衡器分配给他们的请求。您Web应用程序框架(Baxter,如Flask或Django)编写的应用程序逻辑在这些worker中运行。

这种类型的方案更适合具有多个CPU的服务器,因为您可以将工作线程的数量设置为CPU的数量,这样您就可以平衡地利用您的处理器内核,由于全局解释器锁(GIL)的限制,单个Python进程无法实现这一点。

在缺点方面,上面的示意图也清楚地显示了这种方案的主要局限性。我们有五个客户,但只有四个工人。如果所有五个客户端同时发送请求,负载均衡器会将除一个客户端之外的所有请求发送到工作池,而其余的请求必须保留在队列中,等待工作线程变得可用。因此,五分之四的请求会立即得到答复,而剩下的五分之一则需要等待一段时间。服务器优化的关键之一是选择适当数量的工作器,以防止或最小化给定预期负载的请求阻塞。

异步服务器的配置很难画出来,但我会尽力而为:

这种类型的服务器在单个进程中运行,由一个循环控制。这个循环是一个非常有效的任务管理器和调度器,创建任务来执行客户端发送的请求。与长期存在的服务器工作线程不同,异步任务是由循环创建的,用于处理特定的请求,当请求完成时,任务也会被销毁。在任何时候,一个异步服务器都会有成百上千个活动任务,所有这些任务都会在循环管理下执行自己的工作。

您可能想知道异步任务之间的并行性是如何实现的。这是有趣的部分,因为异步应用程序通过独特的协作多任务处理来实现这一点。这是什么意思?当任务需要等待外部事件(例如,来自数据库服务器的响应)时,它不会像同步工作器那样等待,而是告诉循环它需要等待什么,然后将控制权交还给它。当这个任务被数据库阻塞时,循环可以找到另一个就绪任务。最后,数据库将发送一个响应,然后循环将认为第一个任务准备好再次运行,并将尽快恢复它。

暂停和恢复异步任务的能力可能难以抽象理解。为了帮助您将它应用到您已经知道的内容中,您可以考虑在Python中使用await或yield关键字,但是您稍后会发现这并不是实现异步任务的唯一方法。

令人惊讶的是,异步应用程序完全在单个进程或线程中运行。当然,这种类型的并发需要遵循一些规则,所以不能让一个任务占用CPU太久,否则剩下的任务会被阻塞。为了异步执行,所有任务都需要定期暂停,并将控制权交还给循环。为了从异步模式中受益,应用程序需要有经常被I/O阻塞的任务,并且没有太多的CPU工作。Web应用程序通常非常适合,尤其是当它们需要处理大量客户端请求时。

使用异步服务器时,为了最大限度地利用多个CPU,通常需要创建一个混合方案,添加一个负载平衡器,并在每个CPU上运行一个异步服务器,如下图所示:

Python 中实现异步的 2 种方法

我相信你知道,用Python写异步应用,可以用asyncio包,它在co-process的基础上实现了所有异步应用所需要的暂停和恢复特性。yield关键字以及更新的async和await是asyncio异步功能的基础。

Python生态中还有其他基于协同学的异步方案,比如Trio和Curio。而作为所有协同框架中最古老的Twisted,甚至比asyncio出现的还要早。

如果你对编写异步Web应用感兴趣,有很多基于协同学的异步框架可以选择,包括aiohttp、sanic、FastAPI和Tornado。

很多人不知道的是,协程只是用Python编写异步代码的两种方法之一。第二种方法是基于一个名为greenlet的库,您可以用pip安装它。Greenlets类似于coroutine,它们也允许Python函数暂停执行并在稍后恢复,但它们以完全不同的方式实现这一点,这意味着Python中的异步生态系统分为两类。

协同学和greenlets在异步开发方面最有趣的区别在于,前者需要Python语言特有的关键字和特性才能工作,而后者则不需要。我的意思是,基于协同学的应用程序需要用特定的语法编写,而基于greenlet的应用程序看起来几乎就像普通的Python代码。这非常酷,因为在某些情况下,它允许同步代码异步执行,这是基于协同进程的方案(如asyncio)无法做到的。

那么在greenlet方面,有哪些相当于asyncio的库呢?我知道3个基于greenlet的异步包:Gevent、Eventlet和Meinheld,虽然最后一个更像是Web服务器而不是一般的异步库。它们都有自己的异步循环实现,并且都提供了一个有趣的“猴子打补丁”功能,替代Python标准库中的阻塞函数,比如执行网络和线程的函数,并基于greenlets实现等价的非阻塞版本。如果您有一些想要异步运行的同步代码,这些包将会帮助您。

据我所知,唯一明确支持greenlet的Web框架是Flask。这个框架会自动监控,当你想在greenlet Web服务器上运行时,它会相应地自我调整,无需任何配置。这样做的时候,需要注意不要调用阻塞函数,或者,如果要调用阻塞函数,最好用monkey patch“修复”那些阻塞函数。

然而,Flask并不是唯一受益于greenlets的框架。其他Web框架,如Django和Bottle,尽管它们没有greenlet,但也可以通过组合一个greenlet Web服务器并使用monkey-patching来修复阻塞功能,从而异步运行。

异步比同步更快吗?

对于同步和异步应用程序的性能有一个普遍的误解——异步应用程序比同步应用程序快得多。

我需要澄清一下。无论是同步还是异步编写,Python代码的运行速度几乎相同。除了代码,还有两个因素会影响并发应用程序的性能:上下文切换和可扩展性。

上下文切换

在所有正在运行的任务之间公平分配CPU工作,称为上下文切换,会影响应用程序的性能。对于同步应用来说,这个工作是由操作系统完成的,基本上是一个黑盒,不需要配置或者微调选项。对于异步应用程序,上下文切换是通过循环完成的。

的默认循环实现由asyncio提供,用Python编写,效率不是很高。uvloop包提供了一个替代的循环方案,其中一些代码是用C编写的,以获得更好的性能。Gevent和Meinheld使用的事件循环也是用c写的,Eventlet使用的是Python写的循环。

高度优化的异步循环在上下文切换上比操作系统更高效,但是根据我的经验,要看到实际的效率提升,你得运行非常大的并发量。对于大多数应用程序,我认为同步和异步上下文切换之间的性能差距并不明显。

扩展性

我认为异步更快这个神话的来源是异步应用程序通常更有效地使用CPU,可以更好地扩展,扩展模式比同步更灵活。

如果上图中的同步服务器同时收到100个请求,想想会发生什么。该服务器最多只能同时处理4个请求,因此大多数请求将留在队列中,等待分配给它们一个工作器。

相比之下,异步服务器将立即创建100个任务(或者如果使用混合模式,在4个异步工作器上各创建25个任务)。对于异步服务器,所有请求都将被立即处理,而无需等待(尽管,公平地说,这种方案中还会有其他瓶颈会降低速度,比如对活动数据库连接的限制)。

如果这100个任务主要使用CPU,那么同步和异步方案会有类似的性能,因为每个CPU都以固定的速度运行,Python总是以相同的速度执行代码,应用要做的工作也是一样的。但是,如果这些任务需要大量的I/O操作,那么同步服务器只能处理四个并发请求,但无法实现高CPU利用率。另一方面,异步服务器将更好地保持CPU忙碌,因为它并行运行所有这100个请求。

您可能想知道为什么不能运行100个同步工作器。然后,两台服务器将具有相同的并发能力。请注意,每个工作者都需要自己的Python解释器和与之相关的所有资源,以及单独的应用程序副本及其资源。您的服务器和应用程序的大小将决定您可以运行多少个worker实例,但通常这个数字不会很大。另一方面,异步任务非常轻量级,并且在单个工作进程的上下文中运行,因此它们具有明显的优势。

综上所述,当只有以下几种场景时,我们可以说异步可能比同步更快:

  • 有高负载(没有高负载,高并发访问没有优势)
  • 任务是否受限于I/O(如果任务受限于CPU,超过CPU数量的并发性没有帮助)
  • 您可以查看单位时间内处理的平均请求数。如果你看看百特单个请求的处理时间。你不会看到很大的不同。甚至异步可能会更慢,因为异步有更多并发任务争夺CPU。
  • 结论

    本文希望解答异步代码的一些困惑和误解。我希望你能记住以下两个要点:

  • 只有在高负载下,异步应用程序才能比同步应用程序做得更好。
  • 多亏了greenlets,即使您以通用的方式编写代码并使用Flask或Django这样的传统框架,您也可以从异步中受益。
  • 如果你想知道更多关于异步系统如何工作的细节,你可以查看我在YouTube上的PyCon演讲:异步Python完全初学者。

    作者介绍:

    米格尔·格林伯格是一名软件工程师、摄影师和电影制作人,住在爱尔兰的德拉。你可以在脸书、谷歌、LinkedIn、Github和Twitter上关注他。

    原始链接:

    https://blog . miguelgrinberg . com/post/sync-vs-async-python-what-is-the-difference

    本人也转发此文,发私信“获取资料”即可免费获得价值4999元的InfoQ迷你本。点击文末“了解更多”移步InfoQ官网获取最新资讯~

    本文地址:http://www.cangchou.com/9932.html

    欢迎分享,转载请注明来源:聚客百科

    原文地址: http://juke.outofmemory.cn/life/206391.html

    ()
    打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
    上一篇 2022-05-31
    下一篇 2022-05-31

    发表评论

    登录后才能评论

    评论列表(0条)

    保存