协程的优点:
1、进程和线程都面临这内核态与用户态切换导致耗费大量时间,而协程只处于用户态。
2、协程的执行效率非常高,因为他的切换完全是由用户控制,避免了线程之前的切换开销,线程数量越多,同等数量协程优势就越明显。
3、协程不需要锁的机制。只有一个线程不存在同时写的情况,所以不需要对共享资源不需要加锁,运行效率超高
一、使用yield/send实现协程
import time
def A():
while True:
print("-----------A--------------")
yield
time.sleep(0.5)
def B(a):
while True:
print("B is starting")
next(a)
time.sleep(0.5)
if __name__=="__main__":
a=A()
B(a)
二、greenlet
有两个参数
- *run* -- The callable to invoke.
#被调用的函数
- *parent* -- The parent greenlet. The default is the current greenlet
#父greenlet
例一:
from greenlet import greenlet
def C():
while True:
print("**********C*************")
d.switch()
time.sleep(0.5)
def D():
while True:
print("*************D*************")
c.switch()
time.sleep(0.5)
if __name__=="__main__":
"""
"""
c=greenlet(C)
d=greenlet(D)
c.switch()
例二:
父greenlet使用
from greenlet import greenlet
def C():
print("this is son D")
def D():
print("this is parent:D,starting")
c.switch()
print("the parent D,end")
if __name__=="__main__":
d=greenlet(D)
c = greenlet(run=C,parent=d)
d.switch()
注:协程退出去后就无法被调用了
列三:异常处理
def D():
print("this is parent:D,starting")
try:
c.switch()
except Exception as e:
print(e)
print("the parent D,end")
if __name__=="__main__":
d=greenlet(D)
c = greenlet(run=C,parent=d)
d.switch()
子协程的的一场会抛出到父协程的greenlet处
有一个异常是特例,不会被抛到父协程中,那就是”greenlet.GreenletExit”,这个异常会让当前协程强制退出。