1 _______________________________________ 2 | python process | 3 | _________________________________ | 4 | | python thread | | 5 | | _____ ___________________ | | 6 | | | hub | | pool | | | 7 | | |_____| | _____________ | | | 8 | | | | greenthread | | | | 9 | | | |_____________| | | | 10 | | | _____________ | | | 11 | | | | greenthread | | | | 12 | | | |_____________| | | | 13 | | | | | | 14 | | | ... | | | 15 | | |___________________| | | 16 | |_________________________________| | 17 | | 18 | _________________________________ | 19 | | python thread | | 20 | |_________________________________| | 21 | ... | 22 |_______________________________________| 23 24 eventlet.spawnxxx -> Timer -> next_timer 25 evnetlet.sleep -> schedule_call_global -> hub.switch 26 hub.switch -> greenlet.switch -> run -> prepare_timers 27 -> first_timers -> waiter -> poll 28 read/write[eventlet.os] -> trampoline -> add -> listener 29 _______________________________________ 30 | hub | 31 | ____________________________ | 32 | | listener | | 33 | | greenlet | | 34 | |____________________________| | 35 |_______________________________________| 36 37 _______________________________________ 38 | greenthread | 39 | ____________________________ | 40 | | event | | 41 | | main | | 42 | |____________________________| | 43 |_______________________________________|
1 switch endpoint: eventlet.sleep, GreenThread.wait, acquire/release[event] 2 wakeup wait: call[Timer] -> main[GreenThread] -> send[Event] 3 4 note: 1. Only allow root greenlet to invoke eventlet.sleep 5 6 Example debug coroutine: 7 8 import eventlet 9 from eventlet.green import urllib2 10 from eventlet import debug 11 12 debug.hub_listener_stacks(True) 13 debug.hub_timer_stacks(True) 14 #debug.hub_blocking_detection(True) 15 16 urls = [ 17 #"https://www.google.com/intl/en_ALL/images/logo.gif", 18 "http://python.org/images/python-logo.gif", 19 #"http://us.i1.yimg.com/us.yimg.com/i/ww/beta/y3.gif", 20 ] 21 22 23 def fetch(url): 24 print debug.format_hub_timers() 25 #print debug.format_hub_listeners() 26 body = urllib2.urlopen(url).read() 27 return url, body 28 29 pool = eventlet.GreenPool(200) 30 for url, body in pool.imap(fetch, urls): 31 print("got body from", url, "of length", len(body))