Python 异步: 协程(4)

简介: Python 提供一流的协程,具有“coroutine”类型和新的表达式,如“async def”和“await”。它提供了用于运行协程和开发异步程序的“asyncio”模块。

在本节中,我们将更深入地了解协程。

1. 什么是协程

协程是一个可以挂起和恢复的函数。它通常被定义为通用子程序。可以执行子程序,从一点开始,在另一点结束。然而,协程可以执行然后挂起,并在最终终止之前恢复多次。具体来说,协程可以控制它们暂停执行的确切时间。这可能涉及特定表达式的使用,例如 Python 中的“await”表达式,如 Python 生成器中的 yield 表达式。

协程可能因多种原因而暂停,例如执行另一个协程,例如等待另一个任务,或等待一些外部资源,如套接字连接或进程返回数据。

协程用于并发。可以同时创建和执行许多协程。它们可以控制何时挂起和恢复,从而允许它们在并发任务执行时进行合作。这称为协作式多任务处理,不同于通常与线程一起使用的多任务处理,称为抢占式多任务处理。抢占式多任务涉及操作系统选择暂停和恢复哪些线程以及何时这样做,而不是在协作多任务的情况下由任务自己决定。

现在我们对什么是协程有了一些了解,让我们通过将它们与其他熟悉的编程结构进行比较来加深这种理解。

2. 协程与例程和子例程

“例程”和“子例程”在现代编程中通常指的是同一事物。也许更准确地说,例程是程序,而子例程是程序中的函数。例程有子例程。它是一个离散的表达式模块,它被分配了一个名称,可以接受参数并可以返回一个值。

  • 子例程:可按需执行的指令模块,通常已命名,可采用参数并返回值。也称为函数

一个子程序被执行,遍历表达式,并以某种方式返回。通常,一个子程序被另一个子程序调用。协程是子例程的扩展。这意味着子例程是一种特殊类型的协程。

协程在很多方面都像子例程,例如:

  • 它们都是离散的命名表达式模块。
  • 他们都可以接受争论,也可以不接受。
  • 它们都可以返回一个值,也可以不返回。

主要的区别在于它在返回和退出之前选择了多次暂停和恢复执行。协程和子例程都可以调用自己的其他实例。一个子程序可以调用其他子程序。协程执行其他协程。但是,协程也可以执行其他子例程。当一个协程执行另一个协程时,它必须暂停执行并允许另一个协程在另一个协程完成后恢复。这就像一个子程序调用另一个子程序。不同之处在于协程的暂停可能允许任意数量的其他协程也运行。这使得调用另一个协程的协程比调用另一个子例程的子例程更强大。它是协同程序促进的协作多任务处理的核心。

3. 协程与生成器

生成器是一种可以暂停其执行的特殊函数。生成器函数可以像普通函数一样定义,尽管它在暂停执行并返回值时使用 yield 表达式。生成器函数将返回一个可以遍历的生成器迭代器对象,例如通过 for 循环。每次执行生成器时,它都会从上一次挂起的点运行到下一个 yield 语句。

协程可以使用“await”表达式挂起或屈服于另一个协程。一旦等待的协同程序完成,它将从这一点恢复。我们可能会将生成器视为循环中使用的一种特殊类型的协程和协作多任务处理。

在协程被开发之前,生成器被扩展,以便它们可以像 Python 程序中的协程一样使用。这需要大量的生成器技术知识和自定义任务调度程序的开发。这是通过更改生成器和引入“yield from”表达式实现的。

这些后来被弃用,取而代之的是现代的 async/await 表达式。

4. 协程与任务

子例程和协程可能代表程序中的“任务”。但是,在 Python 中,有一个称为 asyncio.Task 对象的特定对象。

协程可以包装在 asyncio.Task 对象中并独立执行,而不是直接在协程中执行。 Task 对象提供异步执行协程的句柄。

  • Task:一个可以独立执行的包装协程。

这允许包装的协程在后台执行。调用协程可以继续执行指令而不是等待另一个协程。Task 不能单独存在,它必须包装一个协程。因此,Task 是协程,但协程不是任务。

5. 协程与线程

协程比线程更轻量级。

  • Thread:与协程相比重量级
  • Coroutine:与线程相比是轻量级的。

协程被定义为一个函数。线程是由底层操作系统创建和管理的对象,在 Python 中表示为 threading.Thread 对象。

  • Thread:由操作系统管理,由 Python 对象表示。

这意味着协程通常可以更快地创建和开始执行并且占用更少的内存。反之,线程的创建和启动速度比协程慢,占用的内存也更多。协程在一个线程内执行,因此一个线程可以执行多个协程。

6. 协程与进程

协程比进程更轻量级。事实上,线程比进程更轻量级。进程是计算机程序。它可能有一个或多个线程。Python 进程实际上是 Python 解释器的一个单独实例。

进程与线程一样,由底层操作系统创建和管理,并由 multiprocessing.Process 对象表示。

  • Process:由操作系统管理,由 Python 对象表示。

这意味着协程的创建和启动速度明显快于进程,并且占用的内存也少得多。协程只是一个特殊的函数,而进程是至少有一个线程的解释器实例。

7. 什么时候将协程添加到 Python

协程扩展了 Python 中的生成器。长期以来,生成器一直在慢慢地向一流的协程迁移。我们可以探索 Python 的一些主要变化以添加协程,我们可以将其视为概率添加 asyncio 的一个子集。像 send() 和 close() 这样的新方法被添加到生成器对象中,以允许它们更像协程。

第二种基于生成器的协程方法被添加到 Python 3.4 作为 Python 生成器的扩展。协程被定义为使用 @asyncio.coroutine 装饰器的函数。协程是通过 asyncio 模块使用 asyncio 事件循环执行的。协程可以通过“yield from”表达式挂起并执行另一个协程

# define a custom coroutine in Python 3.4
@asyncio.coroutine
def custom_coro():
    # suspend and execute another coroutine
    yield from asyncio.sleep(1)

“yield from”表达式仍然可用于生成器,尽管它是一种在协程中暂停执行的弃用方法,有利于“await”表达式。

我们可以说协程是在 Python 3.5 版本中作为一等对象添加的。这包括对 Python 语言的更改,例如“async def”、“await”、“async with”和“async for”表达式,以及协程类型。

相关文章
|
4天前
|
安全 调度 Python
探索Python中的并发编程:协程与多线程的比较
本文将深入探讨Python中的并发编程技术,重点比较协程与多线程的特点和应用场景。通过对协程和多线程的原理解析,以及在实际项目中的应用案例分析,读者将能够更好地理解两种并发编程模型的异同,并在实践中选择合适的方案来提升Python程序的性能和效率。
|
4天前
|
调度 数据库 Python
【专栏】异步IO在处理IO密集型任务中的高效性
【4月更文挑战第27天】本文介绍了Python并发编程和异步IO,包括并发的基本概念(多线程、多进程、协程),线程与进程的实现(threading和multiprocessing模块),协程的使用(asyncio模块),以及异步IO的原理和优势。强调了异步IO在处理IO密集型任务中的高效性,指出应根据任务类型选择合适的并发技术。
|
4天前
|
调度 Python
探索Python中的异步编程:从回调到协程
本文将介绍Python中的异步编程技术,从最初的回调函数到现代的协程模型。通过对比传统的同步编程方式和异步编程的优劣势,我们深入探讨了Python中异步编程的实现原理,以及如何利用asyncio库和async/await关键字来构建高效的异步应用程序。最后,我们还将讨论一些异步编程的最佳实践和常见问题的解决方法。
|
4天前
|
API UED Python
使用Python进行异步HTTP请求的实践指南
使用Python进行异步HTTP请求的实践指南
21 4
|
4天前
|
Python
Python中的协程:异步编程的利器
Python中的协程:异步编程的利器
17 1
|
4天前
|
缓存 安全 Linux
深入探索Python中的协程
深入探索Python中的协程
|
4天前
|
并行计算 数据处理 开发者
Python并发编程:解析异步IO与多线程
本文探讨了Python中的并发编程技术,着重比较了异步IO和多线程两种常见的并发模型。通过详细分析它们的特点、优劣势以及适用场景,帮助读者更好地理解并选择适合自己项目需求的并发编程方式。
|
4天前
|
人工智能 算法 调度
uvloop,一个强大的 Python 异步IO编程库!
uvloop,一个强大的 Python 异步IO编程库!
37 2
|
4天前
|
API 调度 开发者
Python中的并发编程:使用asyncio库实现异步IO
传统的Python编程模式中,使用多线程或多进程实现并发操作可能存在性能瓶颈和复杂性问题。而随着Python 3.5引入的asyncio库,开发者可以利用异步IO来更高效地处理并发任务。本文将介绍如何利用asyncio库实现异步IO,提升Python程序的并发性能。
|
4天前
|
调度 数据库 Python
探索Python中的异步编程:从回调到协程
本文将探讨Python中异步编程的演变过程,从最初的回调函数到现代的协程机制。我们将深入了解异步编程的原理、优势以及如何使用Python的asyncio库来实现高效的异步程序。通过本文,读者将了解到异步编程的基本概念、常见的应用场景,以及如何利用Python的强大功能来提升程序的性能和可维护性。