协程的特点是利用任务的阻塞时间去处理其他任务
处理任务的是线程,而协程是单线程,占用资源由大到小排:多进程>多进程>协程
gevent模块封装greenlet模块,greenlet模块封装yield
在gevent里使用tiem.sleep会失效,需要使用gevent.sleep,或者使用monkey补丁实现替换
如代码因为monkey.patch_all()补丁问题报错,将from gevent import monkey和补丁代码放到最前面尝试
使用协程完成多任务三个例子:
使用yield实现
import time
def func1():
while True:
print("---1---")
time.sleep(0.1)
yield
def func2():
while True:
print("---2---")
time.sleep(0.1)
yield
def main():
t1 = func1()
t2 = func2()
while True:
next(t1)
next(t2)
if __name__ == "__main__":
main()
使用greenlet实现
import time
from greenlet import greenlet
def func1():
while True:
print("---1---")
gr2.switch()
time.sleep(0.1)
def func2():
while True:
print("---2---")
gr1.switch()
time.sleep(0.1)
gr1 = greenlet(func1)
gr2 = greenlet(func2)
# 切换到gr1中运行
gr1.switch()
使用gevent实现
import time
import gevent
from gevent import monkey
# 打补丁,检查所有耗时操作中存在time.sleep(),自动替换为gevent.sleep()
monkey.patch_all()
def func1(n):
for i in range(n):
print(gevent.getcurrent(), i)
time.sleep(0.5) # 如未打补丁monkey,time的延时没有效果
# gevent.sleep(0.5)
def func2(n):
for i in range(n):
print(gevent.getcurrent(), i)
time.sleep(0.5) # 如未打补丁monkey,time的延时没有效果
# gevent.sleep(0.5)
def func3(n):
for i in range(n):
print(gevent.getcurrent(), i)
time.sleep(0.5) # 如未打补丁monkey,time的延时没有效果
# gevent.sleep(0.5)
print("---1---")
g1 = gevent.spawn(func1, 5)
print("---2---")
g2 = gevent.spawn(func2, 5)
print("---3---")
g3 = gevent.spawn(func3, 5)
print("---4---")
# 协程的最大特点就是利用某个任务阻塞的时间去处理其他任务
# 等待执行
gevent.joinall([
gevent.spawn(func1, 5),
gevent.spawn(func2, 5),
gevent.spawn(func3, 5)
])
# g1.join()
# g2.join()
# g3.join()