3

我对非阻塞 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存储的价值在哪里呢?执行恢复时如何访问它?

任何帮助,将不胜感激!

4

1 回答 1

6

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

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

生成器具有与 Tornado 的事件循环相关联的@gen.coroutine魔力,因此调用Future返回的insert值会在事件循环中注册,从而允许生成器在调用完成get时重新启动。insert

于 2014-08-12T05:09:22.827 回答