switch函数——Gevent源码分析

在gevent的源码中,经常能看到switch函数。而不同的类中的switch函数有不同的用法

1. greenlet的switch函数

这里面的greenlet是greenlet库中的greenlet类,它是gevent中的Greenlet类的基类(即Greenlet类是在greenlet类的基础之上的扩展)
在这个基类里面,它的switch函数的作用是:切换到这个greenlet协程中,并执行该协程的任务

  1. 如果这个协程的任务并没有被激活过,则执行self.run函数来执行这个协程的任务
  2. 如果已经被激活,而且正在运行这个协程的任务(即在执行run函数的时候切到了另一个协程中),调用switch函数将回到这个协程的状态(即上次运行的地点)

2. hub的switch函数

首先,主协程hub类继承了greenlet库的greenlet类。下面是hub的switch函数源码:

def switch(self):
	switch_out = getattr(getcurrent(), 'switch_out', None)
	if switch_out is not None:
		switch_out()
	return greenlet.switch(self)

return greenlet.switch(self)这句说明了这个switch函数将返回greenlet类的switch方法(也就是第一类switch,分两种情况: 执行过要切换的协程的run函数,和未执行run),从而实现切换到子协程并执行其任务的作用(即在hub实现协程的切换)

3. Waiter的switch函数

Waiter的switch函数只能被主协程hub调用
以下是switch的源码:

def switch(self, value=None):
	"""Switch to the greenlet if one's available. Otherwise store the value."""
	greenlet = self.greenlet
	if greenlet is None:
		self.value = value
		self._exception = None
	else:
		assert getcurrent() is self.hub, "Can only use Waiter.switch method from the Hub greenlet"
		switch = greenlet.switch
		try:
			switch(value)
		except:
			self.hub.handle_error(switch, *sys.exc_info())

这个switch的作用是切换到可用的协程greenlet的上次执行的地点和状态(也就是上面第一种switch被调用的时候,这个协程已经执行了run函数,则回到上次执行的状态,继续执行),否则就保存value值

posted @ 2015-07-01 21:02  Eric_Nirvana  阅读(1562)  评论(0编辑  收藏  举报