Python---- 协程详解

本文介绍了协程的基本概念,它又称为微线程,可在单线程中协调CPU完成多任务,提高效率。还阐述了协程的使用场景,即大量不需要CPU操作时适用。同时详细讲解了用生成器yield、greenlet、gevent实现协程的方法,以及monkey补丁模块的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

协程

一、协程基本概述

​ 协程 又称为微线程,纤程,英文名(corotine)。从技术的角度来说,“协程就是你可以暂停执行的函数”。可以理解成生成器一样。一句话总结协程就是一个线程里可以协调cpu来完成多任务,提高效率,减少资源的浪费。

​ 协程存在的意义:对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时(保存状态,下次继续)。协程,则只使用一个线程(单线程),在一个线程中规定某个代码块执行顺序。

协程的使用场景:当程序中存在大量不需要CPU操作的时(IO),适用协程;
协程工作原理如下图:
在这里插入图片描述

二、用生成器 yiled 实现协程

1、创建 work1 生成器。

2、创建work2 生成器

3、获取生成器,用next() 运行生成器

import time
def work1():
    while True:
        print("------我是work1------")
        time.sleep(1)
        yield   #程序碰见 yield 会返回一个生成器。
def work2():
    while True:
        print("------我是work2------")
        time.sleep(1)
        yield
if __name__ == '__main__':
    while True:
        next(work1())
        next(work2())

三、greenlet

​ greenlet 是第三方模块。使用greenlet 可以实现协程,可以自行调度微线程,即协程。generator 实现的协程在yiled value 时只能将 value返回给调用者(caller)。而在greenlet中,target.switch(value)可以切换到指定的协程(target),然后yield value。greenlet 用switch 来表示协程的切换,从一个协程切换到另一协程需要显示指定。

greenlet 实现协程的步骤:

1、导入模块 from greenlet import greenlet

2、创建任务 work1 work2

3、创建greenlet 的对象。 g1 = greenlet(work1) ,g2 = greenlet(work1)

4、切换任务 work1里(g2.switch), work2(g1.switch) 两个任务来回切换。

import time
from greenlet import greenlet
def work1():
    while True:
        print("------我是work1------")
        time.sleep(1)
        g2.switch()
def work2():
    while True:
        print("------我是work2------")
        time.sleep(1)
        g1.switch()
if __name__ == '__main__':
    g1 = greenlet(work1)
    g2 = greenlet(work2)
    g1.switch()

四、gevent

​ greenlet 已经是实现了协程,但是这个还需要人工切换,有点麻烦。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent 为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。

grevent也是第三方库。

如何用gevent 实现协程:

1、导入gevent 模块 improt gevent

2、指派任务 gevent.spawn(函数名,参数1,参数2,…) g1 = gevent.spawn(work1)。g1.join , g2.join 让主线程等待程序完成后退出(让程序阻塞)。

有一个耗时操作,1.gevent.sleep(0.5)替换 time.sleep(0.5);2.打补丁让gevent 识别 time.sleep()。

打补丁是在不修改程序源代码的情况下,为程序增加新的功能。

补充: mokey补丁模块

如何打补丁:1) 导入 monkey 模块 from gevent import monkey

​ 2)破解所有补丁 monkey.patch_all()

猴子补丁主要有以下几个用处:

1、在运行时替换方法、属性等

2、在不修改第三方代码的情况下增加新的功能

3、在运行时为内存中的对象增加patch而不是在磁盘的源代码中增加。

#导入模块
from gevent import monkey
#破解所有
monkey.patch_all() 
from gevent import monkey   #导入monkey 补丁模块
monkey.patch_all()
import time
import gevent
def work1():
    while True:
        print("------我是work1------",gevent.getcurrent()) #gevent.getcurrent()  查看哪个协程在执行
        # gevent.sleep(1)
        time.sleep(1)

def work2():
    while True:
        print("------我是work2------",gevent.getcurrent())
        # gevent.sleep(1)
        time.sleep(1)
if __name__ == '__main__':
    g1 = gevent.spawn(work1)
    g2 = gevent.spawn(work2)
    # 让主线程等待程序完成后退出,(让程序阻塞)
    g1.join()
    g2.join()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值