协程的理解以及python实现协程

协程

  1. 协程
    协程是一种比线程更加轻量级的存在,正如一个进程可以拥有多个线程一样,一个线程可以拥有多个协程。协程不是被操作系统内核管理,而是完全由程序所控制。线程和进程的操作是由程序触发系统接口,最后的执行者是系统,协程的操作是程序员。
    ![(https://img-blog.csdnimg.cn/20200110202740145.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzQxOTc1Mw==,size_16,color_FFFFFF,t_70)

  2. 意义:对于多线程的应用,CPU通过切片的方式来切换协程之间的执行,线程之间的切换需要耗时(保存状态,下次继续)。协程则只使用一个线程(单线程),在一个线程中规定某个代码快执行顺序。
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/202001102049549
    协程的应用场景:当程序中存在大量不需要CPU的操作时(IO),适用于协程
    理解:在一个线程中的某个函数,可以在任何地方保存函数的一些临时变量,然后切换到另外一个函数,注意不是通过调用函数的方式做到,并且切换的次数以及何时切换都是由程序员掌控。协程就是可以暂停执行的函数。

  3. 协程的简单实现

"""
1.创建work1的生成器
2.获取work2的生成器
3.获取生成器,通过next运行生成器
"""
# 1.创建work1的生成器
import time


def work1():
    while True:
        print('正在执行work1...')
        yield
        time.sleep(1)


def work2():
    while True:
        print('正在执行work2...')
        yield
        time.sleep(1)


if __name__ == '__main__':
    w1 = work1()
    w2 = work2()
    while True:
        next(w1)
        next(w2)

上面的程序就实现了一个简答的协程。实现单线程两个任务同时切换。

4. greenlet
Greenlet是python的一个C扩展,可以提供可自行调度的微线程,也就是协程。

"""
1.创建work1的生成器
2.获取work2的生成器
3.获取生成器,通过next运行生成器
"""

"""
greenlet实现协程的步骤
1.导入模块
2.创建任务work1,work2
3.创建greenlet对象
4.手动切换任务
"""
# 1.创建work1的生成器
import time
from greenlet import greenlet


def work1():
    while True:
        print('正在执行work1...')
        yield
        time.sleep(1)
        # 切换到第二个任务
        g2.switch()


def work2():
    while True:
        print('正在执行work2...')
        yield
        time.sleep(1)
        # 切换到第一个任务
        g1.switch()


if __name__ == '__main__':

    # 创建greenlet对象
    g1 = greenlet(work1)
    g2 = greenlet(work2)

    # 执行work1
    g1.switch()

5. grvent
由于IO操作非常耗时,经常使程序处于等待状态,有了grevent为我们自动切换协程,就保证greenlet在运行,而不是等待IO。

"""
# 自动识别程序中耗时操作,在耗时的时候自动切换到其他任务
1.导入模块
2.指派任务

"""
# 1.创建work1的生成器
import time
import gevent


def work1():
    while True:
        print('正在执行work1...')
        gevent.sleep(1)


def work2():
    while True:
        print('正在执行work2...')
        # gevent识别不了,time.sleep()是延时操作
        # time.sleep(1)
        gevent.sleep(1)


if __name__ == '__main__':
    # 指派任务
    # gevent.spawn(函数名,参数1,参数2,参数3,....)
    g1 = gevent.spawn(work1)
    g2 = gevent.spawn(work2)

    # 让主线程等待协程执行完毕再退出
    g1.join()
    g2.join()

上面的程序中gevent识别不了time.sleep()是延迟操作,因此有可以使用打补丁的方法:

  1. 导入模块
    from gevent import monkey
  2. 破解monkey.patch_all()
    monkey.patch_all()

上面两步完成之后,就可以识别了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值