Python协程--生成器(实现多任务)

本文介绍了Python协程的概念,通过生成器、greenlet和gevent逐步实现多任务处理。重点讲解了如何使用gevent进行任务调度,并强调了在使用gevent时,需要将耗时操作如time.sleep替换为gevent.sleep,并展示了打补丁的方法。
摘要由CSDN通过智能技术生成

0.生成器

在这里插入图片描述

在这里插入图片描述在这里插入图片描述

1.使用yield完成多任务

import time


def task_1():
    while True:
        print("---1----")
        time.sleep(0.1)
        yield


def task_2():
    while True:
        print("---2----")
        time.sleep(0.1)
        yield


def main():
    t1 = task_1()
    t2 = task_2()
    # 先让t1运行一会,当t1中遇到yield的时候,再返回到24行,然后
    # 执行t2,当它遇到yield的时候,再次切换到t1中
    # 这样t1/t2/t1/t2的交替运行,最终实现了多任务....协程
    while True:
        next(t1)
        next(t2)
    


if __name__ == "__main__":
    main()

运行结果:

---1----
---2----
---1----
---2----
---1----
---2----
---1----
...

2.使用greenlet完成多任务

在这里插入图片描述

from greenlet import greenlet
import time

def test1():
    while True:
        print("---A--")
        gr2.switch()
        time.sleep(0.5)

def test2():
    while True:
        print("---B--")
        gr1.switch()
        time.sleep(0.5)

#创建生成器对象
gr1 = greenlet(test1)
gr2 = greenlet(test2)

#切换到gr1中运行,开始输出
gr1.switch()

运行结果:

---A--
---B--
---A--
---B--
---A--
....

3.使用gevent完成多任务

在这里插入图片描述

import gevent
import time


def f1(n):
    for i in range(n):
        print(gevent.getcurrent(), i)
        # time.sleep(0.5)
        gevent.sleep(0.5) #延时、堵塞等操作,都需要换成gevent里边的相应方法

def f2(n):
    for i in range(n):
        print(gevent.getcurrent(), i)
        # time.sleep(0.5)
        gevent.sleep(0.5) #延时、堵塞等操作,都需要换成gevent里边的相应方法

def f3(n):
    for i in range(n):
        print(gevent.getcurrent(), i)
        # time.sleep(0.5)
        gevent.sleep(0.5)  #延时、堵塞等操作,都需要换成gevent里边的相应方法

print("----1---")
g1 = gevent.spawn(f1, 5)
print("----2---")
g2 = gevent.spawn(f2, 5)
print("----3---")
g3 = gevent.spawn(f3, 5)
print("----4---")
g1.join()   # 堵塞,等待完成
g2.join()   # 堵塞,等待完成
g3.join()   # 堵塞,等待完成

运行结果:

----1---
----2---
----3---
----4---
<Greenlet at 0x15bf8f917b8: f1(5)> 0
<Greenlet at 0x15bf8f918c8: f2(5)> 0
<Greenlet at 0x15bf8f919d8: f3(5)> 0
<Greenlet at 0x15bf8f917b8: f1(5)> 1
<Greenlet at 0x15bf8f918c8: f2(5)> 1
<Greenlet at 0x15bf8f919d8: f3(5)> 1
<Greenlet at 0x15bf8f917b8: f1(5)> 2
<Greenlet at 0x15bf8f918c8: f2(5)> 2
<Greenlet at 0x15bf8f919d8: f3(5)> 2
<Greenlet at 0x15bf8f917b8: f1(5)> 3
<Greenlet at 0x15bf8f918c8: f2(5)> 3
<Greenlet at 0x15bf8f919d8: f3(5)> 3
<Greenlet at 0x15bf8f917b8: f1(5)> 4
<Greenlet at 0x15bf8f918c8: f2(5)> 4
<Greenlet at 0x15bf8f919d8: f3(5)> 4

注意,此时使用的延时是gevent.sleep(0.5),若使用time.sleep(0.5),则输出结果如下:

----1---
----2---
----3---
----4---
<Greenlet at 0x2b3ce8917b8: f1(5)> 0
<Greenlet at 0x2b3ce8917b8: f1(5)> 1
<Greenlet at 0x2b3ce8917b8: f1(5)> 2
<Greenlet at 0x2b3ce8917b8: f1(5)> 3
<Greenlet at 0x2b3ce8917b8: f1(5)> 4
<Greenlet at 0x2b3ce8918c8: f2(5)> 0
<Greenlet at 0x2b3ce8918c8: f2(5)> 1
<Greenlet at 0x2b3ce8918c8: f2(5)> 2
<Greenlet at 0x2b3ce8918c8: f2(5)> 3
<Greenlet at 0x2b3ce8918c8: f2(5)> 4
<Greenlet at 0x2b3ce8919d8: f3(5)> 0
<Greenlet at 0x2b3ce8919d8: f3(5)> 1
<Greenlet at 0x2b3ce8919d8: f3(5)> 2
<Greenlet at 0x2b3ce8919d8: f3(5)> 3
<Greenlet at 0x2b3ce8919d8: f3(5)> 4

4.gevent打补丁

有耗时操作时,需要将程序中用到的耗时操作的代码,替换成gevent中自己实现的模块,比如讲time.sleep(0.5)自动替换gevent.sleep(0.5),需要打补丁,方法如下:

首先导入:from gevent import monkey
然后执行:monkey.patch_all()

import gevent
import time
from gevent import monkey

# 有耗时操作时,需要将程序中用到的耗时操作的代码,替换成gevent中自己实现的模块
monkey.patch_all()


def f1(n):
    for i in range(n):
        print(gevent.getcurrent(), i)
        time.sleep(0.5)

def f2(n):
    for i in range(n):
        print(gevent.getcurrent(), i)
        time.sleep(0.5)

def f3(n):
    for i in range(n):
        print(gevent.getcurrent(), i)
        time.sleep(0.5)

print("----1---")
g1 = gevent.spawn(f1, 5)
print("----2---")
g2 = gevent.spawn(f2, 5)
print("----3---")
g3 = gevent.spawn(f3, 5)
print("----4---")
g1.join()
g2.join()
g3.join()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值