# 了解了greenlet后,再回来学习一下gevent#sleep函数# import gevent# gevent.sleep()'''
sleep的作用很简单,触发一个阻塞的操作,导致调用hub.wait,
从当前greenlet.greenlet切换至Hub,超时之后再从hub切换到之前的greenlet继续执行。
通过这个例子可以知道,gevent将任何阻塞性的操作封装成一个Watcher,
然后从调用阻塞操作的协程切换到Hub,等到阻塞操作完成之后,再从Hub切换到之前的协程。
作者:WolfLC
链接:https://www.jianshu.com/p/f55148c41f54
'''import gevent
deffoo():print('Running in foo')
gevent.sleep(0)print('Explicit context switch to foo again')defbar():print('Explicit context to bar')
gevent.sleep(0)print('Implicit context switch back to bar')
gevent.joinall([
gevent.spawn(foo),
gevent.spawn(bar),])'''
Running in foo
Explicit context to bar
Explicit context switch to foo again
Implicit context switch back to bar
'''#gevent.spawn创建一个新的Greenlet,并注册到hub的loop上,调用gevent.joinall或者Greenlet.join的时候开始切换到hub
import time
import gevent
from gevent.timeout import Timeout
# SLEEP=3# TIMEOUT=2## timeout=Timeout(TIMEOUT)# timeout.start()## def wait():# gevent.sleep(SLEEP)# print("log in wait")## begin=time.time()# try:# gevent.spawn(wait).join()# except Timeout:# print('after %s catch Timeout Exception' % (time.time() - begin))# finally:# timeout.cancel()# after 2.0007071495056152 catch Timeout Exception'''
这个类在gevent.timeout模块,其作用是超时后在当前协程抛出异常,这样执行流程也强制回到了当前协程
'''# SLEEP = 4# TIMEOUT = 5## timeout = Timeout(TIMEOUT)# timeout.start()## def wait():# gevent.sleep(SLEEP)# print('log in wait')## begin = time.time()# try:# gevent.spawn(wait).join()# except Timeout:# print('after %s catch Timeout Exception' % (time.time() - begin))# finally:# timeout.cancel()## gevent.sleep(2)# print('program will finish')'''
一定要记得在finally调用cancel,否则如果协程先于TIMEOUT时间恢复,之后还会抛出异常
Timeout只是切换到当前协程,并不会取消已经注册的协程(上面通过spawn发起的协程)
'''# SLEEP = 6# TIMEOUT = 5### def wait():# gevent.sleep(SLEEP)# print('log in wait')### begin = time.time()# try:# gevent.spawn(wait).join(TIMEOUT)# except Timeout:# print('after %s catch Timeout Exception' % (time.time() - begin))## print('program will exit', time.time() - begin)# program will exit 5.047271251678467'''
gevent对可能导致当前协程挂起的函数都提供了timeout参数,用于在指定时间到达之后恢复被挂起的协程。在函数内部会捕获Timeout异常,并不会抛出
'''# 同步机制# 一种是Semaphore 之前用到过 这个是gevent提供的# Event用来在Greenlet之间同步import gevent
from gevent.event import Event
'''
Illustrates the use of events
'''
evt = Event()defsetter():'''After 3 seconds, wake all threads waiting on the value of evt'''print('A: Hey wait for me, I have to do something')
gevent.sleep(3)print("Ok, I'm done")
evt.set()defwaiter():'''After 3 seconds the get call will unblock'''print("I'll wait for you")
evt.wait()# blockingprint("It's about time")defmain():
gevent.joinall([
gevent.spawn(setter),
gevent.spawn(waiter),
gevent.spawn(waiter),])if __name__ =='__main__': main()'''
A: Hey wait for me, I have to do something
I'll wait for you
I'll wait for you
Ok, I'm done
It's about time
It's about time
wait等待事件发生,如果事件未发生那么挂起该协程;set通知事件发生,然后hub会唤醒所有wait在该事件的协程
'''