我对非阻塞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
的值存储在哪里?执行恢复后如何访问?
任何帮助将不胜感激!
答案 0 :(得分:5)
在var
执行时仍在使用insert
的内存,但get
函数本身已“冻结”,这允许执行其他函数。 Tornado的协同程序是使用Python生成器实现的,它允许在yield
发生时临时暂停函数执行,然后在屈服点之后再次重新启动(保留函数的状态)。以下是PEP that introduced generators:
如果遇到yield语句,则函数的状态为 冻结,并将值[yielding]返回给.next()的调用者。通过 “冻结”我们的意思是保留所有当地的州,包括 当前变量的当前绑定,指令指针和 内部评估堆栈:保存足够的信息以便 下次调用.next()时,该函数可以完全按原样进行 收益率声明只是另一个外部呼叫。
@gen.coroutine
生成器具有与Tornado事件循环相关联的魔力,因此Future
调用返回的insert
已在事件循环中注册,允许{{1 }}生成器在get
调用完成时重新启动。