2016-03-03 68 views
0

龙卷风正在单线程中运行。
在一个时间点,是否只有一个功能运行?
所以我不必锁定保护变量?
即使这些功能是异步的?需要保护龙卷风的全局变量吗?

+1

请添加您的代码和相关信息。请参阅提问的教程http://stackoverflow.com/help/how-to-ask – SkyWalker

回答

0

龙卷风函数不间断运行,直到“yield”表达式(如果函数是协程)或函数返回。所以答案是否定的,你通常不需要用Tornado应用程序中的锁来保护全局变量。

如果您只需要一个协程可以使用共享的全局变量,那么Python的标准线程.Lock就是实现这一目标的错误方法。 (事实上​​,在单线程Tornado应用程序中使用threading.Lock会导致死锁。)而是使用tornado.locks.Lock来协调协程的访问。但这是一种先进的用例,你几乎不用担心。

为背景,读铭文著名的“硬骨头”文章:基于回调

https://glyph.twistedmatrix.com/2014/02/unyielding.html

这是关于双绞线,但对于异步coroutine-和应用程序一般。

+0

前两句似乎在异步,非阻塞堆栈中相互矛盾。 – kwarunek

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() 
+0

你是对的,对不起,我没有描述我的问题。 –