协程,又称微线程,纤程,也称为用户级线程,在不开辟线程的基础上完成多任务,也就是在单线程的情况下完成多任务,多个任务按照一定顺序交替执行 通俗理解只要在def里面只看到一个yield关键字表示就是协程
协程是也是实现多任务的一种方式
协程yield
协程之间执行任务按照一定顺序交替执行
demo:
import time
def work1():
while True:
print("----work1---")
yield
time.sleep(0.5)
def work2():
while True:
print("----work2---")
yield
time.sleep(0.5)
def main():
w1 = work1()
w2 = work2()
while True:
next(w1) #调用生成器,增加yield是将一个函数转变为一个生成器,使用next可以调用
next(w2)
main()
生成器、装饰器、迭代器详解见:
协程greenlet
使用的较少
为了更好使用协程来完成多任务,python中的greenlet模块对其封装,从而使得切换任务变的更加简单,但是还不够简单这里不做过多介绍了。
greenlet已经实现了协程,但是这个还要人工切换,这里介绍一个比greenlet更强大而且能够自动切换任务的第三方库,那就是gevent。
协程gevent
gevent内部封装的greenlet,其原理是当一个greenlet遇到IO(指的是input output 输入输出,比如网络、文件操作等)操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。
由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO
import gevent
import time
from gevent import monkey
# 打补丁,让gevent框架识别耗时操作,比如:time.sleep,网络请求延时
monkey.patch_all()
def work1(n):
for i in range(n):
print("work1....")
time.sleep(0.2)
# 获取当前协程
print(gevent.getcurrent(), i)
def work2(n):
for i in range(n):
print("work2....")
time.sleep(0.2)
# 获取当前协程
print(gevent.getcurrent(), i)
g1 = gevent.spawn(work1,5)
g2 = gevent.spawn(work2,5)
g1.join()
g2.join()
当前程序是一个死循环并且还能有耗时操作,就不需要加上join方法了,因为程序需要一直运行不会退出。如果不增加join那么主进程结束那么协程会停止运行
网友评论