1、简单理解
协程其实就是微线程,针对耗时操作,高效利用CPU。完成多任务操作,一般用于耗时操作:网络请求 网络下载(爬虫) 文件读写 阻塞等。进程、线程、协程大致是一个"进程 > 线程 > 协程"关系。
2、生成器->协程
import time
def task1():
for i in range(1,5):
print('A'*i)
yield
time.sleep(0.5)
def task2():
for i in range(1,5):
print('B' * i)
yield
time.sleep(1)
if __name__ == '__main__':
g1 = task1()
g2 = task2()
while True:
try:
next(g1)
next(g2)
except:
break
3、greenlet模块->协程
from greenlet import greenlet
import time
def a(): #任务A
for i in range(5):
print('A'+str(i))
gb.switch()
time.sleep(0.1)
def b(): #任务B
for i in range(5):
print('B'+str(i))
gc.switch()
time.sleep(0.1)
def c(): #任务C
for i in range(5):
print('C'+str(i))
ga.switch()
time.sleep(0.1)
if __name__ == '__main__':
ga = greenlet(a)
gb = greenlet(b)
gc = greenlet(c)
ga.switch()
4、猴子补丁->协程
greenlet已经实现了协程,但是这个人工切换,是不是觉得太麻烦了,不要着急,python还有以恶比greenlet更强大的并且能够自动切换任务的模块’gevent’。其原理是当一个greenlet遇到IO(指的是input ouput输入输出,比如网络,文件操作等)操作时,比如访问网路,就自动切换到其他的greenlet,等到IO完成。再适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。
import time
import gevent
from gevent import monkey
monkey.patch_all() #打猴子补丁
def a(): #任务A
for i in range(5):
print('A'+str(i))
time.sleep(0.1)
def b(): #任务B
for i in range(5):
print('B'+str(i))
time.sleep(0.1)
def c(): #任务C
for i in range(5):
print('C'+str(i))
time.sleep(0.1)
if __name__ == '__main__':
g1 = gevent.spawn(a)
g2 = gevent.spawn(b)
g3 = gevent.spawn(c)
g1.join()
g2.join()
g3.join()
print('---------------')