龙卷风在单线程中运行 在一个时间点,是否只有一个功能在运行? 所以我不需要锁定来保护变量? 甚至这些函数都是异步的吗?
答案 0 :(得分:0)
龙卷风功能不间断运行,直到"产生"表达式(如果函数是协程)或函数返回。所以答案是否定的,你通常不需要使用Tornado应用程序中的锁来保护全局变量。
如果您只需要一个协程可以使用共享的全局变量,Python的标准线程.Lock是实现此目的的错误方法。 (实际上,在单线程Tornado应用程序中使用threading.Lock会导致死锁。)相反,使用tornado.locks.Lock来协调协同程序'访问。但这是一个高级用例,你几乎肯定不用担心。
有关背景,请阅读Glyph的着名" Unyielding"文章:
https://glyph.twistedmatrix.com/2014/02/unyielding.html
它是关于Twisted的,但通常适用于基于异步协同和回调的应用程序。
答案 1 :(得分:0)
如果在IOLoop中安排了两个或多个使用该变量的函数,则需要保护全局变量。例如。异步处理许多http请求。
您可以使用toro's Lock在龙卷风4.2+中,您可以使用tornado.locks,因为toro已合并到Tornado。
案例:
test_var
并调用依赖函数,这需要更长的时间test_var
示例:
from tornado.ioloop import IOLoop
from tornado import gen
import time
test_var = 'test'
@gen.coroutine
def sleep():
yield gen.Task(IOLoop.instance().add_timeout, time.time() + 0.1)
@gen.coroutine
def depend_on_test_var():
yield sleep()
print('depend_on_test %s' % test_var)
@gen.coroutine
def set_test_var():
global test_var
test_var = 'set'
yield depend_on_test_var()
@gen.coroutine
def clear_test_var():
global test_var
test_var = 'clear'
@gen.coroutine
def main():
print('main start %s' % test_var)
yield [
set_test_var(),
clear_test_var()
]
IOLoop.instance().run_sync(main)
一次运行一个功能。由于非阻塞函数的yield
(asynchttpclient,异步睡眠等)意味着做了其他事情直到完成,ioloop会采取下一个预定函数 - 这有点过度简化了。
当然这仅是示例,可以使用单独的yields
:
@gen.coroutine
def main():
print('main start %s' % test_var)
yield set_test_var()
yield clear_test_var()