Python中协程(coroutine)详解

这篇具有很好参考价值的文章主要介绍了Python中协程(coroutine)详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、协程和线程的比较及其适用场景

1 共用变量问题

多线程中可能出现多个线程争抢变量,所以变量需要加锁;协程中任一时刻都只有一个线程,所以变量不需要加锁。

但是协程虽然不像多线程争抢变量但仍是和多线程一样共用变量的,即共用变量在某处改变在另外一处引用时也会发生改变。

2 协程的适用场景

从资源角度说,协程只有一个线程只能使用一个cpu核,所以它适合用于IO密集(包括磁盘IO和网络IO)函数,并不适用于计算密集函数。

从事情重复性说,协程类似多线程,适用于被反复调用的函数(for或while),也可用于做不同事情的多个函数。

3 协程的切换

线程是由操作系统来控制切换的,并不需要我们自己来调度;但协程在操作系统中表现为一个线程,其调度操作系统无能为力,只得我们自己来实现。

await关键字表示该位置阻塞时可让出cpu执行,即切换到下一协程运行;但追根究底对我们而言好像只有await asyncio.sleep()(另外还有future但这个暂不考虑吧)。

所以各协程间一定要在某个地方(尤其是循环内)使用await asyncio.sleep()谦让给其他协程,不然如果协程一直不谦让那其他协程,那其他协程只能等该协程运行完才能运行了。

二、协程代码实现

1 协程函数的定义

正常函数怎么写就怎么写,在def前面加上async即可。如:

async def say_after(delay, what):
    await asyncio.sleep(delay)
    print(what)

2 协程函数的调用

入口函数使用asyncio.run() 进行调用。如:

import asyncio


async def main():
    print(f"started at {time.strftime('%X')}")

    print('hello world!')

    print(f"finished at {time.strftime('%X')}")

if __name__ == "__main__":
    # 入口函数通过asyncio.run()调用
    asyncio.run(main())

一般协程函数调用时在其前面加上await关键字进行调用:

import asyncio
import time

async def say_after(delay, what):
    await asyncio.sleep(delay)
    print(what)

async def main():
    print(f"started at {time.strftime('%X')}")

    # 在前面加上await进行调用
    # 这种形式和正常的同步执行程序效果上没什么区别,仍是执行完上一步再执行下一步
    await say_after(1, 'hello')
    await say_after(2, 'world')

    print(f"finished at {time.strftime('%X')}")


if __name__ == "__main__":
    # 入口函数通过asyncio.run()调用
    asyncio.run(main())

最后一种是通过asyncio.create_task()调用一般协程函数。

第二种调用方式也是调用一般协程函数,但是如果只是这么调用的话协程函数并没有什么作用,比如上边这个函数耗时仍然和正常的同步版本一样是3秒。

协程的意义在正在于asyncio.create_task()调用形式,asyncio.create_task()可以将协程函数包装成任务,多个任务之间可并行执行。如下写法只耗时2秒。文章来源地址https://www.toymoban.com/news/detail-845601.html

import asyncio
import time

#学习中遇到问题没人解答?小编创建了一个Python学习交流群:153708845
class TestAsync:
    async def say_after(self,delay, what):
        await asyncio.sleep(delay)
        print(what)

    async def main(self):
        print(f"started at {time.strftime('%X')}")

        task_list = []
        # 等价于[1,2]
        for i in range(1, 3, 1):
            # 步骤一、使用asyncio.create_task()调用协程函数,封装成任务
            tmp_task = asyncio.create_task(self.say_after(i, 'hello'))
            task_list.append(tmp_task)

        # 第二步,await任务
        for tmp_task in task_list:
            await tmp_task

        print(f"finished at {time.strftime('%X')}")

if __name__ == "__main__":
    obj = TestAsync()
    asyncio.run(obj.main())

到了这里,关于Python中协程(coroutine)详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity Coroutine 协程

      Unity Coroutine 是一种在 Unity 引擎中实现异步编程的技术,它可以让你在多个帧中分段执行一个函数,而不是一次性地执行完毕。Coroutine 可以使用 yield 语句来暂停和恢复执行,从而实现一些复杂的逻辑和效果,如时间延迟、循环动画、网络请求等。Coroutine 是基于 IEnumerator 接

    2024年02月15日
    浏览(32)
  • 【unity知识点】Unity 协程Coroutine

    Unity 协程是一种特殊的函数,可以在游戏中实现延迟执行、按顺序执行和异步操作等功能。它使用了迭代器(Iterator)的概念,通过 yield 来控制执行流程。下面是 Unity 协程的使用和使用场景的详细介绍。 在脚本中定义一个协程方法,返回值类型为 IEnumerator 。 在协程方

    2024年02月01日
    浏览(38)
  • 【Unity3D日常开发】Unity3D中协程的使用

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 大家好,我是佛系工程师 ☆恬静的小魔龙☆ ,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 最近有小伙伴问协程怎么用、怎么写,我也是会用会写,但是原理不是很明白。 学习了一下,总结出

    2024年02月12日
    浏览(59)
  • TBB库中实现协程(coroutine)的源码说明

    源码请见: https://github.com/oneapi-src/oneTBB/blob/master/src/tbb/co_context.h 在windows系统,TBB(也就是intel 的 oneTBB库),通过windwos fiber(纤程)来实现协程(coroutine)。 创建一个协程,代码很简洁: windows系统中线程(thread)与纤程(fiber)调度示意图,如下图所示 windwos中的纤程和通常说的协程类似,

    2024年02月14日
    浏览(32)
  • Kotlin 协程库v1.7.1的核心模块(kotlinx-coroutines-core)-- kotlinx.coroutines篇

    目录 asContextElement: asCoroutineDispatcher: js asDeferred: asExecutor: js asPromise: async: js await: awaitAll: awaitCancellation: cancelAndJoin: cancelChildren: CancellableContinuation: CancellationException: CloseableCoroutineDispatcher: CompletableDeferred: CompletableJob:  completeWith:  CompletionHandler: CoroutineDis

    2024年02月03日
    浏览(43)
  • 关于 Go 协同程序(Coroutines 协程)、Go 汇编及一些注意事项。

    参考:  Go 汇编函数 - Go 语言高级编程 Go 嵌套汇编 - 掘金 (juejin.cn) 前言: Golang 适用 Go-Runtime(Go 运行时,嵌入在被编译的PE可执行文件之中)来管理调度协同程式的运行。 Go 语言没有多线程(MT)的概念,在 Go 语言之中,每个 Go 协程就类似开辟了一个新的线程,效率上,肯

    2024年01月25日
    浏览(71)
  • 06.2_c/c++开源库boost_coroutine2 协程库

    sudo apt install libboost-coroutine1.71-dev libboost-coroutine不支持.pc格式查看, 支持.cmake导入 cat /usr/lib/x86_64-linux-gnu/cmake/boost_coroutine-1.71.0/boost_coroutine-config.cmake cat /usr/lib/x86_64-linux-gnu/cmake/boost_coroutine-1.71.0/libboost_coroutine-variant-shared.cmake 可知依赖: atomic chrono context thread 从安装路径可知 头

    2024年04月28日
    浏览(40)
  • python正则+多线程(代理)+线程池+协程

    常用元字符 . 匹配除换行符以外的任意字符 w 匹配字幕或数字或下划线 s 匹配任意空白字符 d 匹配数字 n 匹配一个换行符 t 匹配一个制表符 W 匹配非字母或数字或下划线 D 匹配非数字 S 匹配非空白符 a|b 匹配字符a或b () 匹配括号内的表达式,也表示一个组 […] 匹配字符

    2024年02月16日
    浏览(45)
  • 【Python】多线程编程 ① ( 线程相关概念 | 进程 | 线程 | 协程 / 纤程 | 管程 )

    进程 与 操作系统 : 进程 是 操作系统 中 能够独立运行的单元 , 是 操作系统 对 正在运行的 应用程序 的 抽象结构 描述 ; 操作系统 中 运行的每个 应用程序 就是一个进程 ; 一个操作系统中可以运行 多个 进程 ; 每个 应用程序 都会被 操作系统 分配一个 进程 ID ; 多个进程之间

    2024年02月15日
    浏览(38)
  • Python多任务教程:进程、线程、协程

    进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。进程是一种抽象的概念,从来没有统一的标准定义。进程一般由程序、数据集合和进程控制块三部分组成。程序用于描述进

    2024年02月12日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包