spawn
def spawn(func, *args, **kwargs):
"""Create a greenthread to run ``func(*args, **kwargs)``. Returns a
:class:`GreenThread` object which you can use to get the results of the
call.
Execution control returns immediately to the caller; the created greenthread
is merely scheduled to be run at the next available opportunity.
Use :func:`spawn_after` to arrange for greenthreads to be spawned
after a finite delay.
"""
hub = hubs.get_hub()
g = GreenThread(hub.greenlet)
hub.schedule_call_global(0, g.switch, func, args, kwargs)
return g
hubs的作用,在greenlet的官方文档开始就是我们可以自己构造greenlet的调度器,那么hub的第一个作用就是greenthread的调度器。另外一个作用于网络相关,所以hub有多个实现,对应于epoll,select,poll,pyevent等,我们先看前面的第一个作用。
hub在eventlet中是一个单太实例,也也就是全局就这有这一个实例,其包含一个greenlet实例,该greenlet实例是self.greenlet = greenlet(self.run),这个实例就是官方文档说的MAINLOOP,主循环,更加具体就是其中的run方法,是一个主循环。并且该hub还有两个重要的列表变量,self.timers 和 self.next_timers,前者是一个列表,但是在这个列表上实现了一个最小堆,用来存储将被调度运行的greenthread,后者,用来存储新加入的greenthread。
创建一个GreenThread的实例,greenthread继承于greenlet,简单封装了下,该类的构造函数只需要一个参数,父greenlet,然后再自己的构造函数中,调用父类greenlet的构造函数,传递两个参数,GreenTread的main函数和一个greenlet的实例。第二代码就知道,hubs中作为MAINLOOP的greenlet是所有先创建的greenthread的父greenlet。由前面介绍greenlet的例子中,我们可以知道,当调用该greenthread的switch方法时,将会开始执行该才传递给父类的self.main函数。
然后单态的hub调用schedule_call_global函数,该函数的作用可以看其注释,用来调度函数去执行。
def get_hub():
"""Get the current event hub singleton object.
.. note :: |internal|
"""
try:
hub = _threadlocal.hub
except AttributeError:
try:
_threadlocal.Hub
except AttributeError:
use_hub()
hub = _threadlocal.hub = _threadlocal.Hub()
return hub