协程
也是实现多任务的一种方式
又称为微线程, 纤程,也称为用户级线程
在不开辟线程的基础上完成多任务,也就是在单线程的情况下完成多任务
多个任务按照一定顺序交替执行
,通俗理解只要在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)
评论区