" name="sm-site-verification"/>
侧边栏壁纸
博主头像
PySuper 博主等级

千里之行,始于足下

  • 累计撰写 231 篇文章
  • 累计创建 15 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

Python处理多任务(三) -- 协程

PySuper
2019-11-06 / 0 评论 / 0 点赞 / 22 阅读 / 0 字
温馨提示:
本文最后更新于2024-05-28,若内容或图片失效,请留言反馈。 所有牛逼的人都有一段苦逼的岁月。 但是你只要像SB一样去坚持,终将牛逼!!! ✊✊✊

协程也是实现多任务的一种方式

又称为微线程, 纤程,也称为用户级线程

在不开辟线程的基础上完成多任务,也就是在单线程的情况下完成多任务

多个任务按照一定顺序交替执行,通俗理解只要在def里面只看到一个yield关键字表示就是协程

实现多协程一:yield

import time

def work1():
    while True:
        print("demo___")
        yield
        time.sleep(0.5)

def work2():
    while True:
        print("____demo")
        yield
        time.sleep(0.5)

def main():
    i = 1
    while True:
        if i <= 3:
            # 线程的多任务是按照一定的顺序交替执行的
            next(work1())
            next(work2())
        else:
            break
        i += 1

if __name__ == "__main__":
    main()

实现多协程二:greenlet

已经实现了协程,但是还要人工切换

安装 / 导入

pip3 install greenlet

import greenlet

使用

import time
import greenlet

# 任务1
def work1():
    for i in range(5):
        print("work1...")
        time.sleep(0.2)
        # 切换到协程2里面执行对应的任务
        g2.switch()

# 任务2
def work2():
    for i in range(5):
        print("work2...")
        time.sleep(0.2)
        # 切换到第一个协程执行对应的任务
        g1.switch()

if __name__ == '__main__':
    # 创建协程指定对应的任务
    g1 = greenlet.greenlet(work1)
    g2 = greenlet.greenlet(work2)

    # 切换到第一个协程执行对应的任务
    g1.switch()

实现多协程三:gevent

IO 指的是input output输入输出,比如网络,文件操作

IO 非常耗时,gevent自动切换协程,就保证了greenlet运行,而不是等待IO

安装 / 导入

pip3 install gevent

import gevent

使用

# 三个greenlet是依次运行而不是交替执行
import gevent

def work(n):
    for i in range(n):
        # 获取当前协程
        print(gevent.getcurrent(), i)

g1 = gevent.spawn(work, 5)
g2 = gevent.spawn(work, 5)
g3 = gevent.spawn(work, 5)
g1.join()
g2.join()
g3.join()

切换执行

import gevent

def work(n):
    for i in range(n):
        # 获取当前协程
        print(gevent.getcurrent(), i)
        #用来模拟一个耗时操作,注意不是time模块中的sleep
        gevent.sleep(1)

...

实现多协程四:打补丁

  • 打补丁,让gevent框架识别耗时操作,比如:time.sleep,网络请求延时
  • monkey.patch_all()
import gevent
import time
from gevent import monkey

# 打补丁,让gevent框架识别耗时操作,比如:time.sleep,网络请求延时
monkey.patch_all()

# 任务1
def work1(num):
    for i in range(num):
        print("work1....")
        time.sleep(0.2)
        # gevent.sleep(0.2)

# 任务1
def work2(num):
    for i in range(num):
        print("work2....")
        time.sleep(0.2)
        # gevent.sleep(0.2)

if __name__ == '__main__':
    # 创建协程指定对应的任务
    g1 = gevent.spawn(work1, 3)
    g2 = gevent.spawn(work2, 3)

    # 主线程等待协程执行完成以后程序再退出
    g1.join()
    g2.join()

注意

  • 当程序是一个死循环, 并且还能有耗时操作, 就不需要加上join方法了
  • 因为程序需要一直执行, 不会退出
...

g2 = gevent.spawn(work2, 3)
    
    while True:
        print("主线程中执行")
        time.sleep(0.5)
0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区