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”表达式,以及协程类型。

本文由mdnice多平台发布

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容