龙卷风协程函数中的变量会发生什么?


问题内容

我是非阻塞IO概念的新手,但我在理解协程方面有些困难。考虑以下代码:

class UserPostHandler(RequestHandler):
    @gen.coroutine
    def get(self):
        var = 'some variable'
        data = json.loads(self.request.body)
        yield motor_db.users.insert({self.request.remote_ip: data})#asynch non blocking db insert call
        #success
        self.set_status(201)
        print var

get调用该函数时,它将创建字符串var。函数等待motor.insert完成时此变量会发生什么?据我了解,“非阻塞”表示没有线程在等待IO调用完成,并且在等待时没有使用内存。那么,var存储的价值在哪里?恢复执行后如何访问?

任何帮助,将不胜感激!


问题答案:

执行时var仍在使用for的内存insert,但是get功能本身是“冻结的”,允许其他功能执行。Tornado的协程是使用Python生成器实现的,Python生成器允许在ayield发生时临时暂停函数执行,然后在屈服点之后再次重新启动(保留函数的状态)。这是在引入生成器PEP中描述行为的方式:

如果遇到yield语句,则函数的状态将被冻结,并将[yielded]值返回给.next()的调用方。“冻结”是指保留所有局部状态,包括局部变量的当前绑定,指令指针和内部评估堆栈:保存了足够的信息,以便下次调用.next()时,该函数可以就像yield语句只是另一个外部调用一样继续进行。

@gen.coroutine发电机具有魔力它是关系到龙卷风的事件循环,从而使Future由返回insert调用与事件循环注册,使get发电机要在重新启动时insert调用完成。