01. 协程基础

作者: 花间派I风月 | 来源:发表于2020-05-06 21:45 被阅读0次

一、概述

协程 ,又称为微线程,它是实现多任务的另一种方式,只不过是比线程更小的执行单元。因为它自带CPU的上下文,这样只要在合适的时机,我们可以把一个协程切换到另一个协程。
通俗的理解: 在一个线程中的某个函数中,我们可以在任何地方保存当前函数的一些临时变量等信息,然后切换到另外一个函数中执行,注意不是通过调用函数的方式做到的 ,并且切换的次数以及什么时候再切换到原来的函数都由开发者自己确定。
协程拥有自己的寄存器和栈。协程调度切换的时候,将寄存器上下文和栈都保存到其他地方,在切换回来的时候,恢复到先前保存的寄存器上下文和栈,因此:协程能保留上一次调用状态,每次过程重入时,就相当于进入上一次调用的状态。
协程的好处:
1.无需线程上下文切换的开销(还是单线程)
2.无需原子操作(一个线程改一个变量,改一个变量的过程就可以称为原子操作)的锁定和同步的开销
3.方便切换控制流,简化编程模型
4.高并发+高扩展+低成本:一个cpu支持上万的协程都没有问题,适合用于高并发处理
协程缺点:
1.无法利用多核的资源,协程本身是个单线程,它不能同时将单个cpu的多核用上,协程需要和进程配合才能运用到多cpu上(协程是跑在线程上的)
2.进行阻塞操作时会阻塞掉整个程序:如io
协程与线程的差异:
在实现多任务时, 线程切换从系统层面远不止保存和恢复CPU上下文这么简单。操作系统为了程序运行的高效性,每个线程都有自己缓存Cache等等数据,操作系统还会帮你做这些数据的恢复操作,所以线程的切换非常耗性能。但是协程的切换只是单纯地操作CPU的上下文,所以一秒钟切换个上百万次系统都抗的住。

二、协程工作过程

1. yield工作原理

从语法上来看,协程和生成器类似,都是定义体中包含yield关键字的函数。

1. yield在协程中的用法:

  • 在协程中yield通常出现在表达式的右边,例如:datum = yield,可以产出值,也可以不产出--如果yield关键字后面没有表达式,那么生成器产出None。
  • 在协程中yield也可能从调用方接受数据,调用方是通过send(datum)的方式把数据提供给协程使用,而不是next(...)函数,通常调用方会把值推送给协程。
  • 协程可以把控制器让给中心调度程序,从而激活其他的协程。
    所以总体上在协程中把yield看做是控制流程的方式。

2. 协程在运行过程中有四个状态:

  • GEN_CREATE:等待开始执行
  • GEN_RUNNING:解释器正在执行,这个状态一般看不到
  • GEN_SUSPENDED:在yield表达式处暂停
  • GEN_CLOSED:执行结束
import time

def task_1():
    while True:
        print("--This is task 1!--before")
        yield
        print("--This is task 1!--after")
        time.sleep(0.5)

def task_2():
    while True:
        print("--This is task 2!--before")
        yield
        print("--This is task 2!--after")
        time.sleep(0.5)
        
if __name__ == "__main__":
    t1 = task_1()  # 生成器对象
    t2 = task_2()
    # print(t1, t2)
    while True:
        next(t1)  # 1、唤醒生成器t1,执行到yield后,保存上下文,挂起任务;下次再次唤醒之后,从yield继续往下执行
        print("\nThe main thread!\n")  # 2、继续往下执行
        next(t2)  # 3、唤醒生成器t2,....

运行结果如下:


运行结果

三、实现协程的方式

  • yield
  • yield from
  • greenlet库实现协程
  • gevent库实现协程
  • asyncio异步协程

https://blog.csdn.net/weixin_41599977/article/details/93656042

https://www.cnblogs.com/luyuze95/p/11294695.html

相关文章

  • 01. 协程基础

    一、概述 协程 ,又称为微线程,它是实现多任务的另一种方式,只不过是比线程更小的执行单元。因为它自带CPU的上下文...

  • AndroidのKotlin协程

    参考资料:协程基础 1.协程Coroutines基础 1.1 GlobalScope.launch启动一个独立协程...

  • go - 学习笔记

    基础 函数 指针 结构体 接口 错误 协程 通道 基础 函数 指针 结构体 接口 错误 协程 通道

  • Kotlin协程

    协程基础概念[https://zhuanlan.zhihu.com/p/427092689]协程异常处理[http...

  • 协程基础

    一、概念 协程是通过一个线程在不同代码块之间切换执行,从而实现多任务(这里是并发,假的多任务)并发:一个时间段内,...

  • 协程-基础

    第一个协程程序 添加依赖implementation 'org.jetbrains.kotlinx:kotlinx...

  • 协程

    今天面试被问到了协程。。。一脸懵逼,携程倒是听过,协程还真没听过,得恶补基础啊。。 协程,又称微线程,纤程。英文名...

  • 协程原理:函数调用过程、参数和寄存器

    SRS是单进程、单线程、多协程结构,协程(coroutine)背景以后再介绍,这篇文章介绍协程的重要基础,理解了这...

  • kotlin协程

    协程基础 轻量级线程。在一个线程中可以启动多个协程。 在协程中使用同步方式写出异步代码(协程挂起时不会阻塞线程),...

  • 分享Kotlin协程在Android中的使用

    前言 之前我们学了几个关于协程的基础知识,本文将继续分享Kotlin协程的知识点~挂起,同时介绍协程在Androi...

网友评论

    本文标题:01. 协程基础

    本文链接:https://www.haomeiwen.com/subject/yzmgghtx.html